perm filename CLOOPS.MSG[COM,LSP]5 blob
sn#849385 filedate 1987-11-24 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00004 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002
C00003 00003 ∂05-Oct-87 1028 Kahn.pa@Xerox.COM Re: no-applicable-method
C00008 00004 ∂09-Oct-87 1428 Gregor.pa@Xerox.COM [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
C00015 ENDMK
C⊗;
∂05-Oct-87 1028 Kahn.pa@Xerox.COM Re: no-applicable-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Oct 87 10:28:10 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 05 OCT 87 10:17:47 PDT
Date: Mon, 5 Oct 87 10:15:47 PDT
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: no-applicable-method
In-Reply-To: <871002-135007-6157@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871005-101747-1009@Xerox>
> Alternatively, no-applicable-method could search the argument list
for an
> element of the forwarder class to send the message to, else signal
an error.
> This would not make it so dependent on the first argument.
This discussion of forwarders implemented using no-applicable-method is
slipping between classical (first arg) forwarders and multi-method
forwarders. The classical case is pretty well-understood but doesn't
fit with CLOS (as responses to your first proposal pointed out). Here
you are proposing that forwarding happen on the first argument which is
an instance of forwarder class. What's special about the first one?
Forwarding should happen only when the object is actually involved (in
actor terminology -- receiving a message). The first argument which is
an instance of the forwarding class may passed around only to use under
extraordinary conditions (e.g. an error stream) or might be there to
embed in a structure (forwarding should not happen then).
Not only is it possible to start forwarding too soon, but one may miss
cases in which forwarding was intended. A generic function may have a
default method, or have methods that have T specifiers where the
forwarders are possible. no-applicable-method may never get called. An
elegant, but too expensive, solution is to define forwarders as classes
as not under T.
Forwarders are of limitted utility if they only work for generic
functions and not for ordinary functions. CLOS correctly hides that
distinction from callers. But I haven't heard anyone proposing that
ordinary functions call no-applicable-method when they get wrong-type
args.
Another worry I have about no-applicable-method is that it's piggy
backing upon what is essentially an error mechanism
(no-applicable-method). This seems to be a bad idea. (I remember a
lunch discussion during IJCAI-85 about forwarders and CommonLoops. Kent
Pitman argued well against forwarders using such a mechanism.
No-applicable-method may get called when forwarding is inappropriate
(e.g. buggy code).)
Finally, I think one has to be concerned with the efficiency of an
implementation of forwarding where arguments are consed together,
searched, spread out and several generic functions are called.
References
Bobrow's message of Fri, 2 Oct 87 13:50:00 PDT -- Re:
no-applicable-method
∂09-Oct-87 1428 Gregor.pa@Xerox.COM [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 14:28:09 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 14:26:37 PDT
Date: Fri, 9 Oct 87 14:26 PDT
From: Gregor.pa@Xerox.COM
Subject: [goldman@vaxa.isi.edu: miscellaneous CLOS topics]
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871009142641.2.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Following are parts of a message I received with comments about CLOS.
Mostly, these comments address things we have already changed, but I
thought I would send them out anyways so they would be archived and also
so that we could have saved comments from a user about :accessor-prefix
and friends being confusing.
From: goldman@vaxa.isi.edu
Subject: miscellaneous CLOS topics
Date: Tue, 06 Oct 87 18:17:02 PDT
----------------------------------------------------------------
REDEFINING CLASSES
The way this section is worded makes it unclear to me what is supposed
to happen when I make multiple sequential changes to a DEFCLASS, creating
instances of each without accessing the "old" ones -- e.g.,
(DEFCLASS FOO ...)
create instance F1
(DEFCLASS FOO ...)
create instance F2
(DEFCLASS FOO ...)
now I access F1 and F2
Are there supposed to be copies of each obsolete FOO class around,
associated correcly with F1 and F2 so that the correct one is passed
to class-changed?
Also in this section, it states that CHANGE-CLASS preserves EQLness of
slot values for slots that are present in both the old and new class
definitions. Why EQLness, but not EQness?
----------------------------------------------------------------
"The initialization protocol of make-instance is not yet specified"
Is this still the case? I imagine everyone wants to be able to do
more with INITIALIZE-KEYWORDS-AND-VALUES than initialize slots, no?
----------------------------------------------------------------
DEFCLASS
:accessor-prefix, :reader-prefix
The syntax calls for a SYMBOL, but the semantics appears to really just
want a string, so a string should at LEAST be acceptable if not required.
BUT, saying that
"the names of the constructed functions are interned in the package that
is current at the time the defclass form is macro-expanded"
might make things easy on implementors, but it doesn't
do much for me as a poor application writer. As far as I can tell,
I don't have much to say about when an implementation really decides to
macroexpand something. I think there are (at least) two issues to
consider:
1) The decision here should be consistent with where DEFSTRUCT
interns the symbols for its accessors, copier, tester. CLtL is
suitably vague here, saying nothing under the description of :conc-name
and talking about the package at the time the defstruct is "processed"
in the other cases.
2) When I program in CommonLisp, I am used to being concerned about the
*package* setting at the time my source code is READ. So I would like to
feel assured that I can guarantee (preferably by natural means) what
package these symbols will end up in without having to EVEN CONSIDER the
question of the setting of *package* when some implementation chooses to
"process" or "macroexpand" these forms.
I would like to say that the new symbols must be interned in the
package that was current when the DEFCLASS form was read, but that of
course makes no sense. Another possibility is to
really require symbols, not strings, as the defclass syntax says,
and intern in the symbol-package of the prefix symbol, but that would
not work out well in cases where the prefix symbol turned out to be
visible by means of a USES or IMPORT, and not really be the same package
as READ was using. I would at the very least like to be able to
control the package in a simple way, say by permitting a more verbose
specification of the prefix options:
(:reader-prefix "foo-" :package "MYPKG")
I wish I had a really good idea for this, but I don't. I just feel uneasy
about having it defined in terms of MACROEXPAND time.
-------
∂09-Oct-87 1539 RPG Shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
1. We adopt the terms ``local'' and ``shared'' to describe the visibility
or scope of slots. The first, ``local,'' will refer to slots that are
visible to exactly one instance. The second, ``shared,'' will refer to
slots that are visible to a subset of the instances of a given class and
its subclasses. Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
2. We state that a slot with allocation type :instance is a local slot
and a slot with allocation type :class is a shared slot, and that
we leave room for extensions to CLOS in which other allocation types
are possible, but stipulate that only extensions that produce shared
or local slots are allowed.
3. We review all places where the terms ``shared'' and ``local'' are
currently used in the specification and decide whether what we are
saying at each place refers to shared/local slots or to slots whose
allocation types are :class/:instance. If the former, we leave the
wording essentially as it is; if the latter, we change the terminology
to use this wording or its equivalent: a slot with allocation type
:class (or :instance).
-rpg-
∂09-Oct-87 1618 Gregor.pa@Xerox.COM Shared/class;local/instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 16:18:24 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 16:17:54 PDT
Date: Fri, 9 Oct 87 16:17 PDT
From: Gregor.pa@Xerox.COM
Subject: Shared/class;local/instance
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 9 Oct 87 15:39 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871009161758.8.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: 09 Oct 87 15:39 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
This all seems fine except...
2. We state that a slot with allocation type :instance is a local slot
and a slot with allocation type :class is a shared slot, and that
we leave room for extensions to CLOS in which other allocation types
are possible, but stipulate that only extensions that produce shared
or local slots are allowed.
I don't understand this. What does this restriction mean? Why?
-------
∂09-Oct-87 1610 Gregor.pa@Xerox.COM meeting at x3j13
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 16:10:25 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 OCT 87 16:09:22 PDT
Date: Fri, 9 Oct 87 16:09 PDT
From: Gregor.pa@Xerox.COM
Subject: meeting at x3j13
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871009160928.7.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Should we plan to get together the first day of the x3j13 meeting?
We should try to decide about this soon so we can make travel plans.
-------
∂09-Oct-87 1818 Moon@STONY-BROOK.SCRC.Symbolics.COM meeting at x3j13
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Oct 87 18:18:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 252890; Fri 9-Oct-87 21:19:12 EDT
Date: Fri, 9 Oct 87 21:19 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: meeting at x3j13
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <871009160928.7.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <871009211908.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 9 Oct 87 16:09 PDT
From: Gregor.pa@Xerox.COM
Should we plan to get together the first day of the x3j13 meeting?
I had been assuming that we would.
∂09-Oct-87 1820 Moon@STONY-BROOK.SCRC.Symbolics.COM Shared/class;local/instance
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Oct 87 18:19:54 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 252892; Fri 9-Oct-87 21:20:56 EDT
Date: Fri, 9 Oct 87 21:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 9 Oct 87 18:39 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <871009212052.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 09 Oct 87 1539 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Danny and I agreed to the following terminological definition.
No objections from this quarter.
∂10-Oct-87 1404 RPG Writing
To: common-lisp-object-system@SAIL.Stanford.EDU
Could each of you who believes s/he has sent us a final version
of something for the next draft please send me and Linda either
the dates and topics of such messages or the messages themselves once
more so that we can begin integration? Thanks.
-rpg-
∂11-Oct-87 2101 RPG Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
Please vote for indefinite or dynamic.
-rpg-
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/class;local/instance
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:11 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab08849; 12 Oct 87 10:00 EDT
Received: from csl.ti.com by RELAY.CS.NET id aa18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07682; Mon, 12 Oct 87 07:32:30 CDT
Message-Id: <2770028852-5622498@Jenner>
Date: Mon, 12 Oct 87 07:27:32 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Shared/class;local/instance
In-Reply-To: Msg of 09 Oct 87 1539 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
OK.
Patrick.
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: meeting at x3j13
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:21 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac08849; 12 Oct 87 10:00 EDT
Received: from csl.ti.com by RELAY.CS.NET id ab18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07701; Mon, 12 Oct 87 07:33:37 CDT
Message-Id: <2770028924-5626820@Jenner>
Date: Mon, 12 Oct 87 07:28:44 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: meeting at x3j13
In-Reply-To: Msg of Fri, 9 Oct 87 16:09 PDT from Gregor.pa@xerox.com
Should we plan to get together the first day of the x3j13 meeting?
Sounds good.
Patrick.
∂12-Oct-87 0724 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Extent of CALL-NEXT-METHOD
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 07:24:47 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae08849; 12 Oct 87 10:01 EDT
Received: from csl.ti.com by RELAY.CS.NET id ac18349; 12 Oct 87 10:00 EDT
Received: from Jenner by tilde id AA07741; Mon, 12 Oct 87 07:36:04 CDT
Message-Id: <2770029069-5635569@Jenner>
Date: Mon, 12 Oct 87 07:31:09 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Extent of CALL-NEXT-METHOD
In-Reply-To: Msg of 11 Oct 87 2101 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Please vote for indefinite or dynamic.
I vote blank.
Patrick.
∂12-Oct-87 0851 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 08:51:48 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 OCT 87 08:52:24 PDT
Date: Mon, 12 Oct 87 08:52 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 11 Oct 87 21:01 PDT from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871012085217.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
indefinite
-------
∂12-Oct-87 0913 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:13:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 09:11:11 PDT
Date: 12 Oct 87 09:11 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent of CALL-NEXT-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 11 Oct 87
21:01 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871012-091111-3271@Xerox>
indefinite
danny
∂12-Oct-87 0918 Bobrow.pa@Xerox.COM Re: Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:13:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 09:11:11 PDT
Date: 12 Oct 87 09:11 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent of CALL-NEXT-METHOD
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 11 Oct 87
21:01 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871012-091111-3271@Xerox>
indefinite
danny
∂12-Oct-87 1102 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:43:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253478; Mon 12-Oct-87 12:21:45 EDT
Date: Mon, 12 Oct 87 12:21 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 12 Oct 87 00:01 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871012162146.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 11 Oct 87 2101 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Please vote for indefinite or dynamic [extent of CALL-NEXT-METHOD]
I really don't care what the standard says, but if you want me to
predict how Symbolics will implement it, I believe we will implement it
as indefinite extent. Certainly that is how we implement the
corresponding feature of whoppers now. (The extent is optimized to
dynamic if the compiler can prove that dynamic extent is adequate,
otherwise it remains indefinite.)
By the way, the closure captures the method objects, but not the method
functions; in other words, if you redefine a method, then call the
closure, the closure will call the new definition of the next method.
This is the same as the way we treat ordinary function calls in closures
(I don't believe CLtL actually prescribes what should happen in this
case. Should CLOS?)
∂12-Oct-87 1130 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: meeting at x3j13
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:29:55 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:28:55-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:29:44 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:29:30 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:30:36 pdt
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: meeting at x3j13
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 12 Oct 87 07:28:44 -0500.
<2770028924-5626820@Jenner>
Date: Mon, 12 Oct 87 11:30:33 MDT
Message-Id: <14109.561058233@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Should we plan to get together the first day of the x3j13 meeting?
Yes.
jak
∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Shared/class;local/instance
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:43:43 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:43:12-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:44:01 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:43:45 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:44:51 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Shared/class;local/instance
X-Mailer: mh6.5
In-Reply-To: Your message of 09 Oct 87 15:39:00 -0700.
Date: Mon, 12 Oct 87 11:44:48 MDT
Message-Id: <14295.561059088@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Fine.
jak
∂12-Oct-87 1131 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Extent of CALL-NEXT-METHOD
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:43:05 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 10:42:34-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 10:43:13 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 12 Oct 87 13:42:57 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 12 Oct 87 11:42:52 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Extent of CALL-NEXT-METHOD
X-Mailer: mh6.5
In-Reply-To: Your message of 11 Oct 87 21:01:00 -0700.
Date: Mon, 12 Oct 87 11:42:49 MDT
Message-Id: <14272.561058969@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
dynamic
jak
∂12-Oct-87 1145 MASINTER.PA@Xerox.COM extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 11:45:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 11:45:54 PDT
From: MASINTER.PA@Xerox.COM
Date: 12 Oct 87 11:42:48 PDT
Subject: extent of CALL-NEXT-METHOD
To: common-lisp-object-system@Sail.Stanford.Edu
Message-ID: <871012-114554-3632@Xerox>
Dynamic.
∂12-Oct-87 1348 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:48:18 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 OCT 87 13:29:16 PDT
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <19871012162146.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871012132910.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 12:21 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
By the way, the closure captures the method objects, but not the method
functions; in other words, if you redefine a method, then call the
closure, the closure will call the new definition of the next method.
This is the same as the way we treat ordinary function calls in closures
(I don't believe CLtL actually prescribes what should happen in this
case. Should CLOS?)
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
-------
∂12-Oct-87 1351 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:51:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253615; Mon 12-Oct-87 16:52:14 EDT
Date: Mon, 12 Oct 87 16:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870928165521.9.MOON@EUPHRATES.SCRC.Symbolics.COM>,
<871002163721.4.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871012205211.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
After thinking it over, I think Gregor's proposal to simplify the
way setf-functions work is reasonable. There will be some adoption
cost for us, because the order of arguments to a setf function is
being changed from what we agreed on before, but I think we can
come up with a compatibility kludge to take care of that. Of course,
Gregor's proposal doesn't really eliminate the scoping issues, not
only because we cannot get rid of defsetf and define-setf-method,
but also because of the already defined interaction of setf with
macros. However, I think the scoping rules are quite straightforward.
Here is a revised version of what I mailed out on September 28,
modified and simplified to reflect what Gregor proposed:
The goal is to unify the handling of "setf functions" with the handling
of regular functions, so we don't need a proliferation of -setf versions
of defmethod, defgeneric, ensure-generic-function, fboundp, generic-labels,
with-added-methods, etc. The major issue is that Common Lisp has not seen
a need to do this already, so the onus falls on CLOS. In addition, we
ran into difficulty with confusion between the idea of associating a
function name with a function object (in our case, a generic function
object), and the idea of associating a way to setf a function with that
function. This proposal clarifies the situation.
Add to Common Lisp the same concept of "setf functions" that we are
already introducing in CLOS. Right now, Common Lisp only has "setf
macros", which are defined by define-setf-method and both forms of
defsetf. I draw the distinction because a "setf macro" is something
that produces code (or other specifications, as in define-setf-method)
which, when evaluated, will perform the effect of an invocation of setf,
while a "setf function" is something that is called to perform directly
the effect of an invocation of setf.
As with regular functions, associated with any given name you can have a
setf function or a setf macro, but not both. This means that one does
not define a setf function (with defmethod or defgeneric) and also call
defsetf. The mere act of defining the setf function is enough to tell
setf what to do. In fact setf only needs for the setf function to be
defined at run time, not at compile time.
Since setf functions are in a separate, but parallel, namespace from
regular functions, we need a way to name them. The simplest way is to
allow a list (setf -name-) to be used as the name of the setf function
that is called to perform the effect of (setf (-name- ...) ...). The
following functions, macros, and special forms defined in CLtL need to
be enhanced to accept such lists where they now accept symbols as
function names:
compile
defun
disassemble
documentation
fboundp
flet
fmakunbound
function
labels
symbol-function and setf of symbol-function
trace
untrace
and the declarations ftype, function, inline, and notinline
This makes the name of symbol-function a bit obsolete, but I do not
propose to introduce a new function to replace it. The discrepancy is
not that important.
The following functions, macros, and special forms defined in CLOS need
to be enhanced in the same way:
defgeneric
defmethod
ensure-generic-function
generic-flet
generic-labels
with-added-methods
defmethod-setf and defgeneric-setf need to be removed.
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
Note that I do not propose to introduce lexically local setf macros,
that is, a cross between defsetf and macrolet. This does not appear to
be logically necessary. If someone else wants this, it would certainly
not be hard to do. The main issue is whether all three ways of defining
lexically global setf macros need local counterparts. A secondary issue
is whether to define the meaning of defmacro or macrolet of (setf foo).
I also do not now propose to clarify the definition of global setf
macros, for example to say that (macro-function '(setf foo)) returns an
expander function that takes two arguments and returns five values.
These issues logically belong to Common Lisp, not to CLOS.
Contrary to what we already decided about the lambda-list of a
setf-function, the new value to be stored will be passed as the first
argument. Thus, #'(setf foo) takes one more required argument than
#'foo, the first required argument is the new value to be stored, and
the remaining arguments are the same as #'foo's arguments.
The function-defining macros defun, flet, labels, defgeneric, defmethod,
and the :method option to defgeneric, generic-flet, generic-labels, and
with-added-methods will not have a special syntax with two lambda-lists
when defining a setf function, contrary to what we decided before. The
programmer writing a setf-function must know to insert the new-value
parameter at the front of the lambda-list.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour. The following rules for the behavior of SETF suffice; note
that these rules are ordered and the first rule to apply supersedes any
later rules. These rules are a consistent extension of the current
behavior of Common Lisp and the Cleanup committee's resolution of issue
GET-SETF-METHOD-ENVIRONMENT.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf-macro defined for foo, use the setf-macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo) and does not care if that scope is different from the scope
of the function name foo. This allows some nonsensical programs to
be written, but does not seem harmful enough to justify making the
rules more complicated.
Example (for Patrick):
(defmethod (setf subseq)
((new-value vector) (sequence vector) start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (aref sequence i) (aref new-value j))))
If this meets with general approval I will recast this for the Cleanup
committee.
∂12-Oct-87 1357 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent of CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 13:57:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253620; Mon 12-Oct-87 16:58:47 EDT
Date: Mon, 12 Oct 87 16:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent of CALL-NEXT-METHOD
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <871012132910.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871012205849.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
defmethod should behave consistently with defclass and defgeneric in
this respect. The latter two alter an existing object rather than
creating a new object.
∂12-Oct-87 1553 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 15:53:25 PDT
Received: by RELAY.CS.NET id aa14355; 12 Oct 87 18:06 EDT
Received: from relay2.cs.net by RELAY.CS.NET id ah13934; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ag20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19217; Mon, 12 Oct 87 15:10:57 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 14:15:21 CDT
Message-Id: <2770052978-7072022@Jenner>
Date: Mon, 12 Oct 87 14:09:38 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of Wed, 30 Sep 87 12:37 EDT from "David A. Moon"<Moon@scrc-stony-brook.arpa>
In-Reply-To: Msg of Sat, 3 Oct 87 12:59 PDT from Gregor.pa@XEROX.COM
In-Reply-To: Msg of Sat, 3 Oct 87 13:26 PDT from Gregor.pa@XEROX.COM
[From Gregor]
I am still opposed to adding constructors to CLOS. I do believe that
they will make life a little more convenient for some programmers, but I
don't think those advantages outweigh the conceptual problems I outline
above nor do I think they are worth the added complexity of having to
describe and understand how they work and documenting the mechanism
which is used to compile them and cause them to get recompiled when
appropriate.
I don't believe that the programmer's interface (:CONSTRUCTOR option) is
complicated, the rules are like DEFSTRUCT ones.
The meta level is where all the conceptual complexity goes. But
power and reusability are more important than simplicity at this level.
Some people may object about the added code size, but any non trivial
implementation will have to optimize instance creation one way or
another.
As for the discussion about having to edit the constructor option when
the classes are redefined because some initargs would have been changed,
I think that goes in favor of the constructor options, the definition of
the interface is lexically close to where the default initargs are. If
you have a defun form for the constructor, you will have to edit the
defclass form (to edit the default initargs) and the defun form.
I don't think that we should say that constructors are going to be
faster than make-instance but the truth is that they are likely to be on
lots of implementations.
In conclusion since I don't think the option is hard to understand or to
explain and since any serious implementation will have to do something
like that (at the sub-meta level at least), I think it is a good thing
to standardize.
Patrick.
∂12-Oct-87 1615 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 16:15:36 PDT
Received: by RELAY.CS.NET id ab14606; 12 Oct 87 18:26 EDT
Received: from relay2.cs.net by RELAY.CS.NET id ai13934; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ah20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19227; Mon, 12 Oct 87 15:11:07 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 14:46:46 CDT
Message-Id: <2770054846-7184236@Jenner>
Date: Mon, 12 Oct 87 14:40:46 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Danny Bobrow <Bobrow.pa@xerox.com>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: Should redefining a class reinitialize shared slots?
In-Reply-To: Msg of 30 Sep 87 17:30 PDT from Danny Bobrow <Bobrow.pa@xerox.com>
It seems to me the only predictable rules are: (1) all
class slots retain their values when the class is redefined. (2)
all class slots are reinitialized when the class is redefined.
I prefer rule 1 because it is analogous to the rule for
instance slots. Also, it's easier to reinitialize a slot that was
retained than to retain a slot that was reinitialized, if a user
wants to implement behavior different from the default.
I find these arguments strong, but still find rule 2 is most consistent.
Rule 1 probably is desirable in most cases, but I think will be
confusing when we consider the above cases -- again, shades of DWIM. My
intuition is not strong on this, so I would like to see opinions from
Gregor and Patrick (others too, of course).
If we think of those slots as shared instead of class slots, then the
issue of consistency of behavior with local slots becomes more important.
They shouldn't be reinitialized when the class gets redefined.
Patrick.
∂12-Oct-87 1727 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: fixing our problems with setf
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:27:36 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa13933; 12 Oct 87 17:36 EDT
Received: from csl.ti.com by RELAY.CS.NET id aa20424; 12 Oct 87 17:30 EDT
Received: from dsg by tilde id AA19076; Mon, 12 Oct 87 15:07:36 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 12:11:51 CDT
Message-Id: <2770045473-6621103@Jenner>
Date: Mon, 12 Oct 87 12:04:33 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: fixing our problems with setf
In-Reply-To: Msg of Fri, 2 Oct 87 16:37 PDT from Gregor.pa@xerox.com
Also because the expansion of setf does not depend on the argument
list of FOO or (SETF FOO), there can't be any problems with having to
re-expand (recompile) code after the defun for foo or (setf foo)
changes. This rule for setf always puts the new value argument as the
first of the other arguments, this rule always works since it doesn't
depend on the definition of FOO or (SETF FOO).
The point I see in favor of having the new value after all the required
is it suggests that it will be the least significant argument for method
selection. Putting new value first suggests that it will be the most
significant (which is generally not what you want). Besides this
point, the idea of having the combined setf lambda list independent of
the original lambda list is attractive.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour.
Scoping is not a problem in my proposal provided the programmer never
uses defsetf. Because setf always expands the same way, all the
programmer needs to do is provide lexical definitions for the actual
setf function (SETF FOO).
-------
I will be unrealistic to consider that programmers won't use DEFSETF.
All of what Moon included under this issue is still valid.
Patrick.
∂12-Oct-87 1729 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Shared/class;local/instance
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:29:39 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad13933; 12 Oct 87 17:37 EDT
Received: from csl.ti.com by RELAY.CS.NET id ai20424; 12 Oct 87 17:33 EDT
Received: from dsg by tilde id AA19231; Mon, 12 Oct 87 15:11:13 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 12 Oct 87 15:03:07 CDT
Message-Id: <2770055843-7244188@Jenner>
Date: Mon, 12 Oct 87 14:57:23 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Shared/class;local/instance
In-Reply-To: Msg of 09 Oct 87 1539 PDT from Dick Gabriel <RPG@sail.stanford.edu>
Danny and I agreed to the following terminological definition. If y'all
agree, we'll go with it:
1. We adopt the terms ``local'' and ``shared'' to describe the visibility
or scope of slots. The first, ``local,'' will refer to slots that are
visible to exactly one instance. The second, ``shared,'' will refer to
slots that are visible to a subset of the instances of a given class and
its subclasses. Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
I don't think this paragraph is correct if you don't delete the marked
words. Redefining a slot as a shared slot in a subclass S of a class C
affect the visibility of this slots as well. the new slot (seen by the
instances of S) will not be shared with those of C.
Patrick.
∂12-Oct-87 1737 RPG shared/class;local/instance
To: common-lisp-object-system@SAIL.Stanford.EDU
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
Right. I already had deleted it in chapter 1.
-rpg-
∂12-Oct-87 1743 Bobrow.pa@Xerox.COM Re: Shared/class;local/instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 17:43:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 17:43:10 PDT
Date: 12 Oct 87 17:43 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Shared/class;local/instance
In-reply-to: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>'s message of
Mon, 12 Oct 87 14:57:23 CDT
To: DUSSUD@Jenner.csc.ti.com
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <871012-174310-4257@Xerox>
Often this subset is the same as the set of instances of
the class and its subclasses, but a smaller subset can result if a
subclass redefines the slot to be local to its instances.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
I don't think this paragraph is correct if you don't delete the
marked words.
Right.
∂12-Oct-87 1803 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 18:02:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253739; Mon 12-Oct-87 21:03:43 EDT
Date: Mon, 12 Oct 87 21:03 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation Writeup
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871013010341.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Dick, this is the final draft of the Object Creation Writeup, unless
we send you any corrections on Tuesday.
-foo- means the word foo in italics. FOO means the word foo in boldface.
>>>> New Writing
Page 1-5 Creating Instances of Classes
[Replace existing text with this. The goal is to give an overview of
creating instances. It's too early to discuss initialization in detail
because we haven't discussed methods yet.]
The generic function MAKE-INSTANCE creates and returns a new instance of
a class. CLOS provides a flexible means for specifying how a new
instance is initialized. For example, users specify how to fill the
slots with values (either by giving an argument to MAKE-INSTANCE, or by
providing a default initial value). Users can also write methods that
perform extra initialization. The complete initialization protocol is
described in the section "Object Creation and Initialization".
Page 1-27: New Chapter: Object Creation and Initialization
SECTION: Overview
The function MAKE-INSTANCE creates and returns a new instance of a
class. The first argument is a class or the name of a class, and the
remaining arguments are an initarg ("initialization argument") list.
Initialization consists of several distinct steps, including: combining
the explicitly supplied initargs with the default values for the
unsupplied initargs, checking the validity of the initargs, allocating
storage for the instance, filling slots with values, and executing
user-supplied methods that perform additional initialization. CLOS
defines MAKE-INSTANCE in a procedural way, with each step represented by
a generic function. This gives the user the ability to customize any
number of the steps. In addition, MAKE-INSTANCE is a generic function,
allowing the user to replace the entire procedure if so inclined.
CLOS specifies default methods for each step, so there is a well-defined
standard behavior for the entire initialization procedure. For many
programs, the standard behavior is appropriate. The standard behavior
provides users with four simple mechanisms for controlling
initialization:
- Declaring a symbol to be an initarg for a slot, by
by using the :INITARG slot option. This allows one to
provide a value for a slot in a call to MAKE-INSTANCE.
- Supplying a default value form for an initarg, by using the
:DEFAULT-INITARGS class option. This default value is used if the
initarg is not explicitly provided as an argument to MAKE-INSTANCE.
- Supplying a default value form for a slot, by using the :INITFORM
slot option. This default value is stored into the slot if no
initarg associated with that slot is given as an argument to
MAKE-INSTANCE or defaulted by :DEFAULT-INITARGS.
- Defining methods for INITIALIZE-INSTANCE. The slot-filling
behavior described above is implemented by a system-supplied
default method for INITIALIZE-INSTANCE. When users need
to exert greater control over initialization, they can provide
methods for INITIALIZE-INSTANCE. In most cases :AFTER methods
are appropriate for this purpose, because they are called
after the default method that fills the slots, and thus do not
override the normal slot-filling behavior.
Note that the object creation and initialization procedure can be
controlled at two different levels. The standard behavior offers the
four mechanisms mentioned above; this level can be considered the
Programmer Interface level. At the Meta-object level, users can exert
greater control over each step of this procedure; this level can be
considered the interface for experimentation with alternative
object-oriented paradigms.
There is one general guideline that distinguishes between the Programmer
Interface level and the Meta-object levels of programming. To customize
behavior at the Programmer Interface level, the user defines methods
that specialize on instances. That is, the arguments that select
methods are instances. To customize behavior at the Meta-object level,
the user defines methods that specialize on classes. That is, the
arguments that select methods are classes.
This chapter begins by describing the terminology and concepts of the
standard initialization behavior, which is the Programmer Interface.
This chapter then describes the procedural definition of MAKE-INSTANCE.
It briefly mentions the generic functions that implement each step of
the procedure; this is the Meta-object level of initialiation. The
details of these functions are documented in Chapter 3.
SECTION: Terminology Related to Object Creation and Initialization
The terminology related to object creation and initialization is
presented here:
-initarg-. An initarg (initialization argument) is a keyword argument
that can be used to control object creation and initialization. The
&key arguments to MAKE-INSTANCE are initargs. It is often convenient to
use keyword symbols to name initargs, but the name of an initarg can be
any symbol, including NIL. There are two possible purposes for an
initarg: to fill a slot with a value or to provide an argument for
an initialization method. A single initarg can be used for more than
one purpose.
-initarg list-. An initarg list (initialization argument list) is a
list of alternating initarg names and values. Its structure is
identical to a property list and also identical to the portion of an
argument list processed for &key parameters. As in those lists, if an
initarg name appears more than once in an initarg list, the leftmost
occurrence supplies the value and the remaining occurrences are ignored.
The arguments to MAKE-INSTANCE (after the first argument) are an initarg
list. As in an &key argument list, :ALLOW-OTHER-KEYS can appear in an
initarg list, and if its value is non-NIL, error-checking of initarg
names is disabled.
-slot-filling initarg-. An initarg associated with a slot. If
the initarg has a value in the initarg list, the value is stored into
the slot of the newly-created object, overriding any initform associated
with the slot. A single initarg can fill more than one slot. A
slot-filling initarg that fills a shared slot stores its value into the
shared slot, replacing any previous value.
-method-implemented initarg-. An initarg associated with a method. A
method-implemented initarg is intended as an argument for one or more
methods for INITIALIZE-INSTANCE or ALLOCATE-INSTANCE. When an object is
created, the method is called with the initarg's value as an argument
and the method uses the value however it chooses. If the initarg has no
value in the initarg list, the method's lambda-list supplies a default
value.
SECTION: Declaring the Validity of Initargs
MAKE-INSTANCE checks the validity of the initargs and signals an error
if an initarg is supplied that is not valid. An initarg is declared
as valid in the same place where its purpose (whether slot-filling or
method-implemented) is stated.
Slot-filling initargs are declared as valid by the :INITARG slot option
to DEFCLASS. The :INITARG slot option is inherited from superclasses.
Thus, the set of valid slot-filling initargs for a class is the union of
the initargs declared by the class and its superclasses.
Method-implemented initargs are declared as valid by defining methods
for INITIALIZE-INSTANCE or ALLOCATE-INSTANCE. The keyword name of each
keyword parameter specifier in the method's lambda-list becomes a
method-implemented initarg for all classes for which this method is
applicable. Thus, method inheritance controls the set of valid
method-implemented initargs.
The set of valid initargs for a class is the union of the valid
slot-filling initargs, the valid method-implemented initargs, and the
pre-defined initarg :ALLOW-OTHER-KEYS. The default for
:ALLOW-OTHER-KEYS is NIL, and its specification is the same as Common
Lisp defines for &KEY argument lists.
SECTION: Defaulting of Initargs
A -default value form- can be supplied for an initarg. The way to
provide a default value form for either a slot-filling and
method-implemented initarg is to use the :DEFAULT-INITARGS class option.
A default value form is usually specified by a different class from the
class that declared the initarg as valid. Thus, :DEFAULT-INITARGS is
usually used to supply a default value for an inherited initarg.
The :DEFAULT-INITARGS class option is inherited. See ``Inheritance of
Class Options''.
The :DEFAULT-INITARGS class option is followed by alternating initarg
names and forms. Each form is the default value form for the
corresponding initarg. The default value form of an initarg is used
only if that initarg does not appear in the arguments to MAKE-INSTANCE.
In that case, the default value form is evaluated in the lexical
environment of the DEFCLASS form that supplied it, and the resulting
value is used as the initarg's value. The initarg name and value are
appended to the initarg list supplied to MAKE-INSTANCE. The result is
a -defaulted initarg list- in which the explicitly supplied initargs
appear before the defaulted initargs. Defaulted initargs are ordered
according to the order in the class precedence list of the classes
that supplied the default values.
The :DEFAULT-INITARGS option is used only to provide default values for
initargs; it does not declare a symbol as a valid initarg name.
One should distinguish between the purposes of :DEFAULT-INITARGS and
:INITFORM, with respect to slot-filling initargs. The
:DEFAULT-INITARGS class option allows the user to give a default value
form for an initarg without knowing whether or not the initarg fills a
slot. If that initarg is not explicitly supplied in a call to
MAKE-INSTANCE, the default value form is used, just as if it had been
supplied in the call. In contrast, the :INITFORM slot option allows
the user to give a default initial value form for a slot. An :INITFORM
is used only if no initarg associated with that slot is given as an
argument to MAKE-INSTANCE or defaulted by :DEFAULT-INITARGS. The two
kinds of defaulting exist at different levels of abstraction.
Note: CLOS does not guarantee any given order of evaluation of
default-initarg forms and initforms. If there are dependencies among
these forms, INITIALIZE-INSTANCE methods should be used instead. In
most programs, the initforms and default-initarg forms are either
constants or simple forms that construct new objects; forms with
side-effects are permitted, but are not typically used.
SECTION: Rules for Duplication of Initargs
The following rules specify what happens when initargs are duplicated in
various ways.
- The :INITARG slot option may be specified more than once for a given slot.
- A single initarg can initialize more than one slot if the same initarg name
appears in more than one :INITARG slot option.
- It is valid for a given initarg name to be defined more than once as a
slot-filling initarg, as a method-implemented initarg, or both.
- If two initargs that initialize the same slot, with the same or different
names, are given in the arguments to MAKE-INSTANCE, the leftmost of these
initargs in the initarg list prevails. This behavior is consistent
with the behavior of property lists and the portion of an argument
list processed for &key parameters.
- If two different initargs that initialize the same slot have default values,
and neither is given explicitly in the arguments to MAKE-INSTANCE,
the initarg that appears in a :DEFAULT-INITARGS slot option in the most
specific class prevails, or if they appeared in the same class, the one whose
mention in :DEFAULT-INITARGS is leftmost in the DEFCLASS form prevails.
During the defaulting of initargs, the defaults are appended
to the end of the initarg list in this order.
- If there are two different initargs that initialize the same slot, and one
was given explicitly in the arguments to MAKE-INSTANCE while the other was
defaulted via :DEFAULT-INITARGS, the explicit one prevails. (This rule is
implied by the two preceding rules, but it is worth mentioning
explicitly.)
- If a slot has both an :INITFORM and an :INITARG slot option, and the
slot-filling initarg is defaulted via :DEFAULT-INITARGS, the initform is not
used and is not evaluated.
An illustrative example of the above rules:
(defclass a () ((x :initarg a)))
(defclass b (a) ((x :initarg b))
(:default-initargs a 1 b 2))
DEFAULTED
FORM INITARG LIST CONTENTS OF X SLOT
(make-instance 'b) (a 1 b 2) 1
(make-instance 'b 'a 3) (a 3 b 2) 3
(make-instance 'b 'b 4) (b 4 a 1) 4
(make-instance 'b 'a 1 'a 2) (a 1 a 2 b 2) 1
SECTION: Methods for INITIALIZE-INSTANCE
INITIALIZE-INSTANCE is a generic function that uses standard method
combination. Users can define methods for INITIALIZE-INSTANCE to
perform any initialization that cannot be achieved with the simple
slot-filling mechanisms.
CLOS calls the generic function INITIALIZE-INSTANCE after it has:
- Computed the defaulted initarg list by combining the
supplied initarg list with any default initargs
for the class.
- Checked the validity of the defaulted initarg list. If any
of the initargs has not been declared as valid, an error is
signaled.
- Created a blank instance.
CLOS then calls INITIALIZE-INSTANCE with the blank instance and the
defaulted initarg list. The system-supplied default method is a
primary method that initializes the slots with values according to the
initarg list. For each slot (whether local or shared):
- If an initarg in the defaulted initarg list fills that slot, its
value is stored into the slot. (This is true even if a :BEFORE method
has modified the slot.)
- Otherwise, if the slot is uninitialized and it has an initform, the
initform is evaluated and the result is stored into the slot.
- The duplicate-resolution rules mentioned in the section "Rules for
Duplication of Initargs" are obeyed.
Typically, user-defined methods are :AFTER methods; however that is not
a requirement. Users should take care not to supply primary methods
that override the default primary method unless they want to prevent
the normal slot-filling from occurring.
CLOS provides two functions that are useful in the bodies of
INITIALIZE-INSTANCE methods. The function SLOT-BOUNDP returns a
boolean value that states whether the slot is bound or not; this allows
for writing :AFTER methods for INITIALIZE-INSTANCE that initialize slots
only if they have not already been initialized. The function
SLOT-MAKUNBOUND restores a slot to the uninitialized condition.
Implementations are permitted to make certain optimizations of
INITIALIZE-INSTANCE. The description of INITIALIZE-INSTANCE in Chapter
2 mentions the possible optimizations. One possible optimization has
the following impact on user-supplied methods: :BEFORE and :AROUND
methods for INITIALIZE-INSTANCE cannot rely on all the slots being
uninitialized.
SECTION: Procedural Definition of MAKE-INSTANCE
MAKE-INSTANCE behaves as if it were defined as follows, except that
certain optimizations are permitted:
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(check-initargs class initargs)
(let ((instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance))
(defmethod make-instance ((class-name symbol) &rest initargs)
(apply #'make-instance (symbol-class class-name) initargs))
Users can customize this procedure at either the Programmer Interface
level, the Meta-object level, or both.
The Programmer Interface level includes using the :INITFORM, :INITARG,
and :DEFAULT-INITARGS options to DEFCLASS, and defining methods for
INITIALIZE-INSTANCE.
The Meta-object level supports extra customization by defining methods
for: DEFAULT-INITARGS, CHECK-INITARGS, and ALLOCATE-INSTANCE.
Chapter 3 documents each of these generic functions and the
system-supplied default methods.
As noted above, certain optimizations of the MAKE-INSTANCE procedure are
permitted. The description of INITIALIZE-INSTANCE in Chapter 2 mentions
some possible optimizations to this procedure. Additional
optimizations are possible, including inlining and constant-folding of
method lookup and method bodies, provided that the programming
environment either prohibits redefining these methods or updates
everything when they are redefined. One approach might be for
MAKE-INSTANCE to have a separate method for every class, which is
automatically written and compiled by the system.
Because of optimization, methods for the meta-object generic functions
listed may not actually be called on every call to MAKE-INSTANCE, or may
not receive exactly the arguments that would be expected. For example,
CHECK-INITARGS might actually be called before DEFAULT-INITARGS rather
than after, if it has already been determined that the default initargs
will pass CHECK-INITARGS.
>>>> Mechanical Tasks:
Page 1-8: inheritance of :initarg
The :INITARG slot-option is inherited from superclasses. The set of
initargs that initialize a given slot is the union of the sets of initargs declared
in :INITARG slot-options with the same slot name in the class and its
superclasses.
Page-9: inheritance of :default-initargs (the only class option that is
inherited)
The :DEFAULT-INITARGS class option is inherited; the set of initargs for
a class that are defaulted is the union of the sets of initargs
specified in :DEFAULT-INITARGS class options of the class and its
superclasses. When more than one default value form is supplied for a
given initarg, the default value form supplied by the class that appears
earliest in the class precedence list is used.
Page 1-21: Congruent Lambda-lists for All Methods of a Generic Function
Replace the old rules with the new ones.
Probably should add a note about on 1-21 about this:
The proposal assumes CL-Cleanup issue KEYWORD-ARGUMENT-NAME-PACKAGE:ANY, which
stated that the names of &key arguments do not have to be keyword symbols.
The terminology of CLtL is used for discussing keyword arguments, but it
should be understood that keyword names are not necessarily symbols in
the keyword package; that's just a default convention.
Page 2-15 (and onward) DEFCLASS section
Add :INITARG and :DEFAULT-INITARGS to the syntax diagram.
Add this info:
The :INITARG -name- slot-option -declares- an initarg named -name- and
-specifies- that this initarg initializes the slot to which the
slot-option is attached. -name- is any symbol. If the initarg has a
value, the value is stored into the slot and the slot's :INITFORM, if
any, is -not- evaluated. If no initarg specified to initialize a given
slot has a value, then the slot is initialized according to the
:INITFORM (if any). This slot option can appear any number of times.
The :DEFAULT-INITARGS option is followed by a list of alternating
initarg names and default-initarg forms. If one of these initargs does
not appear in the initarg list supplied to MAKE-INSTANCE, the
corresponding default-initarg form is evaluated, then the initarg name
and the form's value are added to the end of the initarg list. The form
is evaluated every time it is used. The lexical environment in which
this form is evaluated is the lexical environment in which DEFCLASS was
evaluated. The dynamic environment is the dynamic environment in which
MAKE-INSTANCE was called. The :DEFAULT-INITARGS option may be specified
more than once. However, an error is signaled if an initarg name
appears more than once in a single :DEFAULT-INITARGS option, or in more
than one :DEFAULT-INITARGS option for a single class.
>>>> Add descriptions of each of these functions to Chapter 2:
(MAKE-INSTANCE -class- &key -initargs-...) => -instance-
Users call this function to create objects. Class can be either a class or
the name of a class. Meta-users can define new methods for MAKE-INSTANCE
to replace the object-creation protocol. For details, see
the section "Object Creation and Initialization".
(INITIALIZE-INSTANCE instance &key &allow-other-keys)
MAKE-INSTANCE calls this with the freshly-created instance, any initargs that
were supplied to MAKE-INSTANCE, and any defaulted initargs. Users define
methods for this to create method-implemented initargs. Typically,
user-defined methods are :AFTER methods, however that is not a requirement.
The primary method for INITIALIZE-INSTANCE is system-supplied and takes care
of the slot-filling initargs. For each slot (whether local or shared):
- if an initarg was specified or defaulted that fills that slot, its
value is stored into the slot. (This is true even if a :BEFORE method
has modified the slot.)
- otherwise, if the slot is uninitialized and it has an initform, the
initform is evaluated and the result is stored into the slot.
- the duplicate-resolution rules mentioned in the section "Rules for
Duplication of Initargs" are obeyed.
Implementations are permitted to optimize initforms that neither
produce nor depend on side-effects, by evaluating them and storing them
into slots before running any INITIALIZE-INSTANCE methods, rather than
handling them in the primary INITIALIZE-INSTANCE method. (This might be
implemented by having the ALLOCATE-INSTANCE method copy a prototype
instance.)
Implementations are permitted to optimize default value forms for
slot-filling initargs by not actually consing the complete initarg list,
when the only method that would see the complete list is the
system-supplied primary method, e.g. when no other methods use &REST.
In this case default value forms can be treated like initforms. This
has no visible effects other than a performance improvement.
(SLOT-BOUNDP instance slot-name) => boolean
Allows writing INITIALIZE-INSTANCE :AFTER methods that only initialize slots if
they haven't been initialized already.
(SLOT-MAKUNBOUND instance slot-name) => instance
Restores a slot to the uninitialized condition.
>>>> Add descriptions of each of these functions to Chapter 3
>>> Functions underlying the tools
It is undefined what happens if you modify the values returned by any
of the functions in this section. It is permitted, but not required,
for an implementation to return values that share with internal data
structures. Some of these functions will be SETF'able; which ones
remain to be determined.
(CLASS-ALL-INITARGS class) => list of initarg names, including inherited
ones. This is (REDUCE #'UNION (MAPCAR #'CLASS-DIRECT-INITARGS cpl)).
(CLASS-DIRECT-INITARGS class) => list of initarg names. This works by
computing the applicable methods for ALLOCATE-INSTANCE and for
INITIALIZE-INSTANCE and examining their lambda-lists (using
METHOD-KEYWORD-NAMES), then combining that with the class's list of
slot-filling initargs.
(CLASS-ALL-INITARG-DEFAULTS class)
=> ((initarg-name default-value-function default-value-form)...)
(CLASS-DIRECT-INITARG-DEFAULTS class)
=> ((initarg-name default-value-function default-value-form)...)
This reflects the :DEFAULT-INITARGS option. Default-value-form is the form
that was originally specified, and is retained purely for explanatory
purposes. default-value-function is what gets actually called; its effect is
equivalent to enclosing default-value-form in the appropriate lexical
environment. Default-value-function takes no arguments.
(CLASS-ALL-SLOT-INITARGS class) => ((initarg-name slot-name...)...)
(CLASS-DIRECT-SLOT-INITARGS class) => ((initarg-name slot-name...)...)
This reflects the :INITARG slot-option.
(COMPUTE-APPLICABLE-METHODS generic argument-list) => list of methods
(METHOD-KEYWORD-NAMES method) => list of symbols or &ALLOW-OTHER-KEYS,
indicating the keyword names of the keyword parameter specifiers in
the method's lambda-list. The result is the symbol &ALLOW-OTHER-KEYS
instead of a list if the method's lambda-list contains that symbol.
>>> Meta-object functions
(ALLOCATE-INSTANCE class &key &allow-other-keys) => instance
Meta-users can replace the system-supplied, implementation-dependent method
for this. Any keyword arguments accepted by applicable ALLOCATE-INSTANCE
methods become valid initargs.
(CHECK-INITARGS class initarg-list)
Meta-users could replace the system-supplied method that implements the
normal rules for initarg validity.
(DEFAULT-INITARGS class initarg-list) => initarg-list
The system-supplied method implements the :DEFAULT-INITARGS class option
by appending initargs that do not appear in initarg-list to the end
of the returned list. The initarg-list supplied as an argument is not
modified. The order of initargs appended to the list is determined by
the duplicate-initarg rules listed earlier.
(FINALIZE-INHERITANCE class &key slots methods initargs)
This is called by the system at least once before a class is instantiated, and
is called again whenever anything relevant changes. System-supplied methods
for this conspire with methods for CHECK-INITARGS, etc., to make MAKE-INSTANCE
faster. Users with their own optimization needs can add methods for this
generic function that will precompute things based on inherited information,
and update the precomputed information whenever anything changes.
The :slots, :methods, and :initargs arguments are booleans that are true
when the specified type of inheritance needs to be recomputed.
∂12-Oct-87 1814 Moon@STONY-BROOK.SCRC.Symbolics.COM Object Creation Writeup
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Oct 87 18:14:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 253752; Mon 12-Oct-87 21:15:43 EDT
Date: Mon, 12 Oct 87 21:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation Writeup
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <19871013010341.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871013011546.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
The fact that constructors are completely missing from the referenced
message indicates that I'm treating constructors as a separable issue.
It does not indicate that I think CLOS should not have constructors.
I'm still digesting the mail on the subject (some of which is giving
me indigestion).
∂13-Oct-87 0910 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Name Change for Metaobject Protocol?
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 13 Oct 87 09:10:06 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Tue 13 Oct 87 09:08:54-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Tue, 13 Oct 87 09:10:05 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 13 Oct 87 12:09:43 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 13 Oct 87 10:10:49 pdt
To: common-lisp-object-system@sail.stanford.edu
Subject: Name Change for Metaobject Protocol?
X-Mailer: mh6.5
Date: Tue, 13 Oct 87 10:10:47 MDT
Message-Id: <3225.561139847@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
I'd like to suggest consideration of a name change for the metaobject
protocol. There were a number of occurances at OOPSLA which lead
me to think this may be a good idea. The one which stands out best
in my mind is Pierre Cointe's presentation at the CLOS working group,
where he presented an example of a metaclass (METAPOLYGON) which was
a metaclass in the Smalltalk sense, but not in the CLOS sense.
From talking to other people, this misconception seemed widespread.
My understanding about what we mean by the metaobject or metaclass
protocol is a collection of classes and methods which can be used
to implement new object oriented languages or extend the semantics of the
CLOS user level language, in a manner similar to the way macros can be used
to extend the syntax of Lisp. Additionally, one could look at the CLOS
metaclass protocol as a restricted version of Pattie Mais' reflection,
in the sense that it is a way of interrogating or modifying the language
semantics. What we do not mean is a class which acts as a "factory
instance" for creating and initializing classes, or a class which somehow
acts as a prototype (in the delegation sense) for other classes, though
one could use the metaobject protocol to define a metaclass which did
that.
As start, I'd like to suggest two possible names. Once is macro protocol or
semantic macro protocol, to draw an analogy with syntactic macros. The other is
reflective level protocol. The advantage of the first is that current Lisp
users will be able to make easy contact with it, the advantage of the
second is that it is perhaps more precise.
This issue may sound trivial, but, unfortunately, we are burdened with
history here, since Smalltalk and Objective-C have already appropriated
the name. While most Lisp programmers may not be bothered by this,
the confusion in OO circles is definitely there.
∂13-Oct-87 0930 Bobrow.pa@Xerox.COM Re: Name Change for Metaobject Protocol?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 09:30:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 09:29:56 PDT
Date: 13 Oct 87 09:29 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Name Change for Metaobject Protocol?
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Tue, 13 Oct 87
10:10:47 MDT
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <871013-092956-4931@Xerox>
My understanding about what we mean by the metaobject or
metaclass protocol is a collection of classes and methods which can
be used to implement new object oriented languages or extend the
semantics of the CLOS user level language, in a manner similar to
the way macros can be used to extend the syntax of Lisp.
Additionally, one could look at the CLOS metaclass protocol as a
restricted version of Pattie Mais' reflection, in the sense that it
is a way of interrogating or modifying the language semantics.
We do mean this, but not only this.
What we do not mean is a class which acts as a "factory
instance" for creating and initializing classes, or a class which
somehow acts as a prototype (in the delegation sense) for other
classes, though one could use the metaobject protocol to define a
metaclass which did that.
We also mean this. It is important to note that having access to the
implementation level of the object system c(the metaobject protocol) an
facilitate making trivial changes as well as more far reaching one. We
do not want to separate ourselves from these.
Hence I believe the name is well chosen, though I would not mind a well
chosen phrase usining "reflection" However, since our metaobject
protocol encompasses both the trivial things that Smalltalk metaclasses
do, as well as the reflective things that Pattie Maes does, and most
people do not know the term reflection, I think we are OK the way we
are.
∂13-Oct-87 1021 Gregor.pa@Xerox.COM Name Change for Metaobject Protocol?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 10:21:03 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 10:21:23 PDT
Date: Tue, 13 Oct 87 10:21 PDT
From: Gregor.pa@Xerox.COM
Subject: Name Change for Metaobject Protocol?
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <3225.561139847@hplabsz>
Message-ID: <871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Note: I apologize in advance for the terseness of this message. All the
messages I will be sending for a while will be compact as well; Its hard
to type with one hand.
The objects in the meta-object protocol are the objects which implement
the (metacircular) evaluator. So the current name is just right.
It is true than one can implement other sorts of object systems by
modifying the CLOS interpreter (using the meta object protocol). These
can be reflective or not, the key fact is that we have made the
interpreter accessible and that it is metacircular.
-------
∂13-Oct-87 1052 Gregor.pa@Xerox.COM fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 10:52:14 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 13 OCT 87 10:52:53 PDT
Date: Tue, 13 Oct 87 10:51 PDT
From: Gregor.pa@Xerox.COM
Subject: fixing our problems with setf
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871012205211.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 16:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
After thinking it over, I think Gregor's proposal to simplify the
way setf-functions work is reasonable. There will be some adoption
cost for us, because the order of arguments to a setf function is
being changed from what we agreed on before, but I think we can
come up with a compatibility kludge to take care of that. Of course,
Gregor's proposal doesn't really eliminate the scoping issues, not
only because we cannot get rid of defsetf and define-setf-method,
but also because of the already defined interaction of setf with
macros. However, I think the scoping rules are quite
straightforward.
Right, what it does do is make the scoping rules simpler and allows a
style in which there is no desire to lexically bind setf macros.
Here is a revised version of what I mailed out on September 28,
modified and simplified to reflect what Gregor proposed:
I just have a couple of comments on your writeup.
As with regular functions, associated with any given name you can have a
setf function or a setf macro, but not both. This means that one does
not define a setf function (with defmethod or defgeneric) and also call
defsetf. The mere act of defining the setf function is enough to tell
setf what to do. In fact setf only needs for the setf function to be
defined at run time, not at compile time.
2 comments
* one could very well have defsetf of FOO and a function named (setf
foo). This might be weird, but nothing prevents it from happening.
* the meaning of the last sentence would be more clear if the next to
the last sentence was removed and the last sentence changed to:
"In the absence of any setf macro definition, SETF expands into a call
to the setf function. This means that the setf function only needs to
be defined at run time, not compile time."
I would like to see what you send to cleanup beforehand if possible.
But I do not expect to read my mail the last half of this week or the
first half of next, so that might make it impossible.
-------
∂13-Oct-87 1103 Gregor.pa@Xerox.COM Extent of CALL-NEXT-METHOD
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:03:20 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 13 OCT 87 10:55:53 PDT
Date: Tue, 13 Oct 87 10:55 PDT
From: Gregor.pa@Xerox.COM
Subject: Extent of CALL-NEXT-METHOD
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <19871012205849.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013105540.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 16:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Mon, 12 Oct 87 13:29 PDT
From: Gregor.pa@Xerox.COM
It seems to me that this has to do with whether defmethod (and friends)
replace the existing method or alter the existing method. I thought
defmethod replaced the existing method; so it seems to me that if the
closure captures the method objects redefining one of the captured
methods should have no effect on the closure.
defmethod should behave consistently with defclass and defgeneric in
this respect. The latter two alter an existing object rather than
creating a new object.
I am not sure that these nust behave consistently. The objects being
defined are different. A class is a large complex structure which is
linked with a lot of things, experience has shown it is useful to update
rather than replace it. A method is smaller and less linked, it may be
reasonable to replace rather than update it. I don't have a really
strong opinion about this (yet), I just wanted to point out that I don't
see consistency as a particularly strong argument here.
-------
∂13-Oct-87 1103 Gregor.pa@Xerox.COM reinitializing class slots
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:03:25 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 11:00:55 PDT
Date: Tue, 13 Oct 87 11:00 PDT
From: Gregor.pa@Xerox.COM
Subject: reinitializing class slots
To: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
cc: Danny Bobrow <Bobrow.pa@Xerox.COM>,
Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <2770054846-7184236@Jenner>
Message-ID: <871013110025.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Mon, 12 Oct 87 14:40:46 CDT
From: Patrick H Dussud <DUSSUD@Jenner.csc.ti.com>
If we think of those slots as shared instead of class slots, then the
issue of consistency of behavior with local slots becomes more important.
They shouldn't be reinitialized when the class gets redefined.
I agree.
-------
∂13-Oct-87 1114 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:14:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254248; Tue 13-Oct-87 14:15:33 EDT
Date: Tue, 13 Oct 87 14:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013181532.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 13 Oct 87 10:51 PDT
From: Gregor.pa@Xerox.COM
I just have a couple of comments on your writeup.
I would like to see what you send to cleanup beforehand if possible.
But I do not expect to read my mail the last half of this week or the
first half of next, so that might make it impossible.
I think resolving this setf stuff is important, so I will attempt to
send out a revised version of my proposal, plus a cleanup committee
proposal, later today, to try to give you time to comment on it.
Have as good a time as it is possible to have in a hospital.
∂13-Oct-87 1348 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 13:48:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254492; Tue 13-Oct-87 16:45:14 EDT
Date: Tue, 13 Oct 87 16:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Here is the proposal I will send to the cleanup committee Wednesday
evening, after incorporating any comments you have to offer:
Issue: SETF-CLOS
References: setf rules for what -place- can be (pp.94-7)
compile function (p.438)
defun macro (p.57)
disassemble function (p.439)
documentation function (p.440)
fboundp function (p.90)
flet special form (p.113)
fmakunbound function (p.92)
ftype declaration (p.158)
function special form (p.87)
function declaration (p.159)
inline declaration (p.159)
notinline declaration (p.159)
labels special form (p.113)
symbol-function and setf of symbol-function (p.90)
trace macro (p.440)
untrace macro (p.440)
Category: ADDITION
Edit history: Version 1, 13-Oct-87 Moon
Problem description:
The Common Lisp Object System needs a well-defined way to relate the
name and arguments of a setting function to those of a reading function,
because both functions can be generic and can have user-defined methods.
We tried to hide the name and arguments of the setting function with
macrology, but the complexity got out of hand. It seems better to make
this information explicit; the version of the CLOS specification that
assumes the adoption of proposal SETF-CLOS:SETF-FUNCTIONS is much
simpler in the relevant areas.
Proposal (SETF-CLOS:SETF-FUNCTIONS):
Add to Common Lisp the concept of "setf functions". Right now, Common
Lisp only has "setf macros", which are defined by define-setf-method and
both forms of defsetf. Terminology:
- a "setf macro" is something that produces code (or other
specifications, as in define-setf-method) which, when evaluated,
will perform the effect of an invocation of setf.
- a "setf function" is something that is called to perform
directly the effect of an invocation of setf.
The name of the setf function that is called to perform the effect of
(setf (-name- ...) ...) is a list (setf -name-), where -name- is a
symbol. The functions, macros, and special forms defined in CLtL and
listed in the References section above need to be enhanced to accept
such lists in addition to symbols as function names.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
A definition of a setf function can be lexically local, like a
definition of a reading function. The following rules specify the
behavior of SETF; note that these rules are ordered and the first rule
to apply supersedes any later rules. These rules are a consistent
extension of the current behavior of Common Lisp and the Cleanup
committee's resolution of issue GET-SETF-METHOD-ENVIRONMENT. Only
rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf macro defined for foo, use the setf macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo). It does not matter if that scope is different from the
scope of the function name foo. This allows some nonsensical programs
to be written, but does not seem harmful enough to justify making more
complicated rules to compare the scopes of the two function definitions.
Normally one does not define both a setf function and a setf macro
for the same reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET or LABELS.
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Test Case: (really more of an example than a test case)
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
Rationale:
By making the names and arguments of setting functions explicit, CLOS is
considerably simplified.
Current practice:
A few Common Lisp implementations already have a similar feature,
in that they have setting functions named (SETF reader). I don't
know of any implementation that has precisely the proposed feature.
Adoption Cost:
The main cost is generalization of a few functions to accept lists
beginning with SETF where they now accept only symbols. Implementations
must add a data structure to store the function definition of a setf
function, however, this can trivially be done with property lists or
generated symbols.
The cost of making the SETF macro expand into a call to a setf function,
when it does not find a setf macro or a regular macro to expand, is
negligible.
This will be an incompatible change for Symbolics, since it already has
setf functions but they do not take the same arguments as proposed here.
However, the change is considered worthwhile.
Cost of non-adoption:
Non-adoption of this proposal would be a significant roadblock to the
Common Lisp Object System. Some major rethinking of CLOS would be
required.
Benefits:
Allow CLOS to be defined without out-of-hand complexity.
Conversion Cost:
None, this is an upward-compatible change.
Esthetics:
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question, however by
stressing setf functions SETF could become easier to teach.
Discussion:
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
The following related features were considered but are specifically
not being proposed at this time, since they are unnecessary for CLOS
and appear not to improve the simplicity and esthetics of the language:
Lexically local setf macros, that is, a cross between defsetf and
macrolet. This does not appear to be logically necessary. Do all three
ways of defining lexically global setf macros need local counterparts?
Should we define the meaning of defmacro or macrolet of (setf foo)?
This would be a fourth way to define a setf macro.
Should we enhance the definition of global setf macros, for example to
say that (macro-function '(setf foo)) returns an expander function that
takes two arguments and returns five values?
Should we introduce a new name for symbol-function, since it accepts
non-symbols now?
∂13-Oct-87 1427 RPG Status
To: common-lisp-object-system@SAIL.Stanford.EDU
LGD and I are working (like mad) on the spec. I am concentrating
on the concepts chapter and Linda on the functions chapter.
Slot description inheritance, congruence, and 1/3 of the object
creation sections supplied by Moon have been incorporated into
the concepts chapter. As I go I am building up a list of
further minor tasks. This list slowly increases, so that I doubt
that we can meet the Oct 16 deadline for completion of the first
pass of the rewrite. I expect that mid-to-late next week is more like
it.
This will require very fast turnaround from you folks on the draft.
-rpg-
∂13-Oct-87 1436 Moon@STONY-BROOK.SCRC.Symbolics.COM fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 14:36:09 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254575; Tue 13-Oct-87 17:36:18 EDT
Date: Tue, 13 Oct 87 17:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013105134.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871013213622.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here is a revision of what I mailed out yesterday, revised to reflect
Gregor's comments. If this differs from the CL-cleanup draft proposal
I mailed out a few minutes ago, that proposal supersedes this one.
The goal is to unify the handling of "setf functions" with the handling
of regular functions, so we don't need a proliferation of -setf versions
of defmethod, defgeneric, ensure-generic-function, fboundp, generic-labels,
with-added-methods, etc. The major issue is that Common Lisp has not seen
a need to do this already, so the onus falls on CLOS. In addition, we
ran into difficulty with confusion between the idea of associating a
function name with a function object (in our case, a generic function
object), and the idea of associating a way to setf a function with that
function. This proposal clarifies the situation.
Add to Common Lisp the same concept of "setf functions" that we are
already introducing in CLOS. Right now, Common Lisp only has "setf
macros", which are defined by define-setf-method and both forms of
defsetf. I draw the distinction because a "setf macro" is something
that produces code (or other specifications, as in define-setf-method)
which, when evaluated, will perform the effect of an invocation of setf,
while a "setf function" is something that is called to perform directly
the effect of an invocation of setf.
Since setf functions are in a separate, but parallel, namespace from
regular functions, we need a way to name them. The simplest way is to
allow a list (setf -name-) to be used as the name of the setf function
that is called to perform the effect of (setf (-name- ...) ...). The
following functions, macros, and special forms defined in CLtL need to
be enhanced to accept such lists where they now accept symbols as
function names:
compile
defun
disassemble
documentation
fboundp
flet
fmakunbound
function
labels
symbol-function and setf of symbol-function
trace
untrace
and the declarations ftype, function, inline, and notinline
This makes the name of symbol-function a bit obsolete, but I do not
propose to introduce a new function to replace it. The discrepancy is
not that important.
The following functions, macros, and special forms defined in CLOS need
to be enhanced in the same way:
defgeneric
defmethod
ensure-generic-function
generic-flet
generic-labels
with-added-methods
defmethod-setf and defgeneric-setf need to be removed.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
Normally one does not define both a setf function and a setf macro
for the same reading function.
A definition of a setf function can be lexically local, like a
definition of a reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET, LABELS, GENERIC-FLET, GENERIC-LABELS, or
WITH-ADDED-METHODS.
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
Note that I do not propose to introduce lexically local setf macros,
that is, a cross between defsetf and macrolet. This does not appear to
be logically necessary. If someone else wants this, it would certainly
not be hard to do. The main issue is whether all three ways of defining
lexically global setf macros need local counterparts. A secondary issue
is whether to define the meaning of defmacro or macrolet of (setf foo).
I also do not now propose to enhance the definition of global setf
macros, for example to say that (macro-function '(setf foo)) returns an
expander function that takes two arguments and returns five values.
These issues logically belong to Common Lisp, not to CLOS.
Contrary to what we already decided about the lambda-list of a
setf-function, the new value to be stored will be passed as the first
argument.
The function-defining macros defun, flet, labels, defgeneric, defmethod,
and the :method option to defgeneric, generic-flet, generic-labels, and
with-added-methods will not have a special syntax with two lambda-lists
when defining a setf function, contrary to what we decided before. The
programmer writing a setf-function must know to insert the new-value
parameter at the front of the lambda-list.
The remaining issue is a scoping issue. We have introduced lexically
local setf functions, where before Common Lisp only had lexically global
setf macros. Thus the namespace of setf operators has been extended to
have a lexical component, just like the namespace of regular operators.
(Recall that "operator" means the union of functions, macros, and
special forms). Regular functions and setf functions naturally come in
pairs, but since they are defined separately we have to specify what
happens in various cases where only one is defined at a given lexical
contour. The following rules for the behavior of SETF suffice; note
that these rules are ordered and the first rule to apply supersedes any
later rules. These rules are a consistent extension of the current
behavior of Common Lisp and the Cleanup committee's resolution of issue
GET-SETF-METHOD-ENVIRONMENT. Only rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf-macro defined for foo, use the setf-macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo) and does not care if that scope is different from the scope
of the function name foo. This allows some nonsensical programs to
be written, but does not seem harmful enough to justify making the
rules more complicated.
Example (for Patrick):
(defmethod (setf subseq)
((new-value vector) (sequence vector) start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (aref sequence i) (aref new-value j))))
∂13-Oct-87 1459 Gregor.pa@Xerox.COM fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 14:59:00 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 13 OCT 87 14:59:16 PDT
Date: Tue, 13 Oct 87 14:59 PDT
From: Gregor.pa@Xerox.COM
Subject: fixing our problems with setf
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871013145903.8.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Tue, 13 Oct 87 16:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I have just a couple of comments. I put them in as comments rather than
editing your text so it would be easier to see them. Otherwise this
looks good, it seems the best compromise between what I have been
wanting to do with setf for sometime and backward compatibility.
Here is the proposal I will send to the cleanup committee Wednesday
evening, after incorporating any comments you have to offer:
Issue: SETF-CLOS
References: setf rules for what -place- can be (pp.94-7)
compile function (p.438)
defun macro (p.57)
disassemble function (p.439)
documentation function (p.440)
fboundp function (p.90)
flet special form (p.113)
fmakunbound function (p.92)
ftype declaration (p.158)
function special form (p.87)
function declaration (p.159)
inline declaration (p.159)
notinline declaration (p.159)
labels special form (p.113)
symbol-function and setf of symbol-function (p.90)
trace macro (p.440)
untrace macro (p.440)
Category: ADDITION
Edit history: Version 1, 13-Oct-87 Moon
Problem description:
The Common Lisp Object System needs a well-defined way to relate the
name and arguments of a setting function to those of a reading function,
because both functions can be generic and can have user-defined methods.
We tried to hide the name and arguments of the setting function with
macrology, but the complexity got out of hand. It seems better to make
this information explicit; the version of the CLOS specification that
assumes the adoption of proposal SETF-CLOS:SETF-FUNCTIONS is much
simpler in the relevant areas.
Proposal (SETF-CLOS:SETF-FUNCTIONS):
Add to Common Lisp the concept of "setf functions". Right now, Common
Lisp only has "setf macros", which are defined by define-setf-method and
both forms of defsetf. Terminology:
- a "setf macro" is something that produces code (or other
specifications, as in define-setf-method) which, when evaluated,
will perform the effect of an invocation of setf.
- a "setf function" is something that is called to perform
directly the effect of an invocation of setf.
You should say right here that a setf function is called by the default
expansion of setf (unless a setf macro was explicitly defined).
The name of the setf function that is called to perform the effect of
(setf (-name- ...) ...) is a list (setf -name-), where -name- is a
symbol. The functions, macros, and special forms defined in CLtL and
listed in the References section above need to be enhanced to accept
such lists in addition to symbols as function names.
A setf function receives the new value to be stored as its first
argument. Thus, #'(setf foo) should have one more required parameter
than #'foo, the first required parameter is the new value to be stored,
and the remaining parameters should be the same as #'foo's parameters.
A setf function must return its first argument, since setf is defined
to return the new value.
A definition of a setf function can be lexically local, like a
definition of a reading function. The following rules specify the
behavior of SETF; note that these rules are ordered and the first rule
to apply supersedes any later rules. These rules are a consistent
extension of the current behavior of Common Lisp and the Cleanup
committee's resolution of issue GET-SETF-METHOD-ENVIRONMENT. Only
rule 4 is new with this proposal.
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function definition,
rather than a locally defined function or macro, and if there is a
setf macro defined for foo, use the setf macro to compute the expansion.
(2) If the function-name foo is defined as a macro in the current scope,
use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in the current
scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Note that rule 4 is independent of the scope of the function name
(setf foo). It does not matter if that scope is different from the
scope of the function name foo. This allows some nonsensical programs
to be written, but does not seem harmful enough to justify making more
complicated rules to compare the scopes of the two function definitions.
Normally one does not define both a setf function and a setf macro
for the same reading function.
Normally one defines a local reading function and a local setf function
together in a single FLET or LABELS.
(I give an example later).
In the absence of any setf macro definition, SETF of a function expands
into a call to the setf function. This means that the setf function
only needs to be defined at run time, not compile time.
Should be "Since in the absence of ..."?
Test Case: (really more of an example than a test case)
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional end)
(unless end (setq end (length sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
Another example would be:
(defun frobulate (mumble)
(let ((table (mumble-table mumble)))
(flet ((foo (x)
(gethash x table))
((setf foo) (new x)
(setf (gethash x table) new)))
..
(foo a)
..
(setf (foo a) b))))
Rationale:
By making the names and arguments of setting functions explicit, CLOS is
considerably simplified.
This reduces the desire having a way to lexially bind setf macros
because code which doesn't use defsetf or define-modify-macro won't need
lexical setf macros it can just use lexical functions.
It would be good to point out that right now, many people are doing
something *like* this:
(defsetf foo |setf FOO|)
(defun foo (x) ..)
(defun |setf FOO| (x new) ..)
and that these many similar styles will all be able to be expressed
with:
(defun foo (x) ..)
(defun (setf foo) (new x) ..)
The bringing together of these styles will make code more 'common'. I
tried to capture this in the following paragraph but it doesn't quite
get it.
Many of the current styles of using setf are quite similar. That code
will be be simplified because many people who have been using techniques
essentially equivalent to using setf functions with no setf macros in
the new technique will begin using a common mechanism.
Current practice:
A few Common Lisp implementations already have a similar feature,
in that they have setting functions named (SETF reader). I don't
know of any implementation that has precisely the proposed feature.
Adoption Cost:
The main cost is generalization of a few functions to accept lists
beginning with SETF where they now accept only symbols. Implementations
must add a data structure to store the function definition of a setf
function, however, this can trivially be done with property lists or
generated symbols.
The cost of making the SETF macro expand into a call to a setf function,
when it does not find a setf macro or a regular macro to expand, is
negligible.
This will be an incompatible change for Symbolics, since it already has
setf functions but they do not take the same arguments as proposed here.
However, the change is considered worthwhile.
Cost of non-adoption:
Non-adoption of this proposal would be a significant roadblock to the
Common Lisp Object System. Some major rethinking of CLOS would be
required.
Benefits:
Allow CLOS to be defined without out-of-hand complexity.
Conversion Cost:
None, this is an upward-compatible change.
Esthetics:
SETF would be more esthetic, but less powerful, if it had only the
proposed setf functions and did not have setf macros. Such a major
incompatible change is of course out of the question, however by
stressing setf functions SETF could become easier to teach.
perhaps "by stressing the use of setf functions and no explicit setf
macros SETF could become easier to teach.".
I really believe that many people will stop defining setf macros once
this proposal is accepted.
Discussion:
Note that in Common Lisp, setf macroexpansion is an operation on
function names, not on functions. It differs from some dialects of
Scheme, such as T, in this respect. This proposal does not attempt to
change that.
The following related features were considered but are specifically
not being proposed at this time, since they are unnecessary for CLOS
and appear not to improve the simplicity and esthetics of the language:
Lexically local setf macros, that is, a cross between defsetf and
macrolet. This does not appear to be logically necessary. Do all three
ways of defining lexically global setf macros need local counterparts?
Should we define the meaning of defmacro or macrolet of (setf foo)?
This would be a fourth way to define a setf macro.
Should we enhance the definition of global setf macros, for example to
say that (macro-function '(setf foo)) returns an expander function that
takes two arguments and returns five values?
Should we introduce a new name for symbol-function, since it accepts
non-symbols now?
-------
∂13-Oct-87 1817 Bobrow.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 18:17:45 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 18:18:23 PDT
Date: 13 Oct 87 18:18 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: fixing our problems with setf
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Tue, 13 Oct 87 16:45 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Gregor.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-181823-5939@Xerox>
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function
definition, rather than a locally defined function or macro, and if
there is a setf macro defined for foo, use the setf macro to
compute the expansion.
(2) If the function-name foo is defined as a macro in the
current scope, use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in
the current scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
Normally one does not define both a setf function and a setf
macro for the same reading function.
But if a (setf foo) is defined locally, it is always be used, whether or
not foo is defined locally or globally, right???
I think the rule might be stated that if there is no (setf foo) function
AND there is a setf macro, then the macro is used, else the (setf foo)
function is used in the expansion. This is a slightly extended version
of your:
In the absence of any setf macro definition, SETF of a function
expands into a call to the setf function.
But aside from these two glitches (or my misunderstanding), I agree.
danny
∂13-Oct-87 1845 Pavel.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 18:45:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 18:45:51 PDT
Date: Tue, 13 Oct 87 18:45:44 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: <871013-181823-5939@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-184551-5973@Xerox>
Date: 13 Oct 87 18:18 PDT
From: Danny Bobrow <Bobrow.pa>
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
Isn't it the case that lexical functions cannot have a SETF method in
CLtL? I believe that in the following code:
(defsetf foo set-foo)
(flet ((foo (x) ...))
(setf (foo 7) 8))
the function SET-FOO will not be called. Instead, SETF should signal an
error complaining about how there isn't a SETF method for the lexical
function FOO. The SETF method for the global function FOO is not used.
Am I just hallucinating about this?
Pavel
∂13-Oct-87 1900 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 19:00:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254770; Tue 13-Oct-87 22:00:32 EDT
Date: Tue, 13 Oct 87 22:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-184551-5973@Xerox>
Message-ID: <19871014020034.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Tue, 13 Oct 87 18:45:44 PDT
From: Pavel.pa@Xerox.COM
Isn't it the case that lexical functions cannot have a SETF method in
CLtL?
CLtL doesn't say, but the CL-Cleanup committee decided about half a year
ago, in resolving issue GET-SETF-METHOD-ENVIRONMENT, that what you say
is true. See the handout from the June X3J13 meeting.
I believe that in the following code:
(defsetf foo set-foo)
(flet ((foo (x) ...))
(setf (foo 7) 8))
the function SET-FOO will not be called. Instead, SETF should signal an
error complaining about how there isn't a SETF method for the lexical
function FOO. The SETF method for the global function FOO is not used.
That's correct.
Am I just hallucinating about this?
If so, you're hallucinating the same way as the Cleanup committee.
∂13-Oct-87 1904 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 87 19:04:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254778; Tue 13-Oct-87 22:05:21 EDT
Date: Tue, 13 Oct 87 22:05 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-181823-5939@Xerox>
Message-ID: <19871014020527.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 13 Oct 87 18:18 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Rules for the macroexpansion of (setf (foo x) y):
(1) If the function-name foo refers to the global function
definition, rather than a locally defined function or macro, and if
there is a setf macro defined for foo, use the setf macro to
compute the expansion.
(2) If the function-name foo is defined as a macro in the
current scope, use macroexpand-1 to expand (foo x) and try again.
(3) If the function-name foo is defined as a special form in
the current scope, signal an error.
(4) Expand into the equivalent of
(let ((#:temp-1 x)
(#:temp-2 y))
(funcall #'(setf foo) #:temp-2 #:temp-1))
Do (1) and (4) together imply that if there is a macro definition for
foo, and there is an flet foo, but no (setf foo) defined, that the
expansion of
(setf (foo ...)...)
uses (funcall #'(setf foo) ...) rather than the macro. This seems wrong
(inconsistent with CLtL ???).
CLtL doesn't say anything about calling #'(setf foo).
Yes, local function definitions shadow global macros and global setf macros.
This is what the cleanup committee already decided. See the handout from
the June X3J13 meeting, issue GET-SETF-METHOD-ENVIRONMENT.
A program that defines a local foo without defining a (setf foo) is an
example of the nonsensical programs alluded to in my message.
Normally one does not define both a setf function and a setf
macro for the same reading function.
But if a (setf foo) is defined locally, it is always be used, whether or
not foo is defined locally or globally, right???
setf is an operation on function names, not functions, so when we say
that a given form expands into (funcall #'(setf foo) ...), that is independent
of the scoping of (setf foo). Whatever (setf foo) is in scope gets called,
even if its scope is less than the scope of foo. Another way to write
nonsensical programs, perhaps. Of course one doesn't need setf at all
to write nonsensical programs!
I think the rule might be stated that if there is no (setf foo) function
AND there is a setf macro, then the macro is used, else the (setf foo)
function is used in the expansion. This is a slightly extended version
of your:
In the absence of any setf macro definition, SETF of a function
expands into a call to the setf function.
But aside from these two glitches (or my misunderstanding), I agree.
You've just restated the more complicated rule that Gregor just
convinced me to get rid of. Maybe you should talk to him (preferably
before he metamorphoses).
∂13-Oct-87 2009 Pavel.pa@Xerox.COM Re: fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 87 20:09:28 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 87 20:07:00 PDT
Date: Tue, 13 Oct 87 20:01:00 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: <19871013204504.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871013-200700-6060@Xerox>
A nit in your test case. It would be nicer if the optional variable end
had a default value rather than using the (unless end ...) hack:
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional (end (length
sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
∂14-Oct-87 0827 @STONY-BROOK.SCRC.Symbolics.COM,@JUNCO.SCRC.Symbolics.COM:skeene@STONY-BROOK.SCRC.Symbolics.COM status of "object" or "standard-object"
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Oct 87 08:27:26 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 255053; 14 Oct 87 11:28:07 EDT
Date: Wed, 14 Oct 87 11:27 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: status of "object" or "standard-object"
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Last month we discussed whether CLOS should specify the class "object"
or "standard-object", and we didn't get anywhere.
To me, this seems to be a hole in the spec that we ought to fill up in
time for the next draft. It seems like most people believe there will
be one or more of these classes, but the spec doesn't say anything at
all about them. Unless we do something, our draft will imply that
there won't be these classes, but we will still be assuming there will
be.
The spec excludes these classes quite explicitly, in the CPL examples.
The class precedence lists include all the user-defined classes and T,
but nothing else. Also, the section on Meta Objects makes no mention
of "object" or "standard-object".
We could either make a decision on this, or include it in the spec under
a new section "Issues still under Discussion". It might happen that
other issues will have the same uncertain status at the November
deadline. Constructors are presently in that category as well.
∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: status of "object" or "standard-object"
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 09:50:48 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 09:37:23-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 09:37:15 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 12:36:56 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 09:36:15 pdt
To: "Sonya E. Keene" <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: status of "object" or "standard-object"
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 14 Oct 87 11:27:00 -0400.
<871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: Wed, 14 Oct 87 09:36:12 MDT
Message-Id: <1519.561224172@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> We could either make a decision on this, or include it in the spec under
> a new section "Issues still under Discussion". It might happen that
> other issues will have the same uncertain status at the November
> deadline. Constructors are presently in that category as well.
My feeling on this is that all references to subjects covered in Part 3
(metaobject protocol) should be qualified as still under discussion.
The qualification need not be local to the reference, but could be
global to Part 1. When we meet in November (or possibly via. e-mail
before) we can perhaps finalize, but to do otherwise would be unfair
to Dick and Linda.
jak
∂14-Oct-87 0950 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Name Change for Metaobject Protocol?
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 09:50:51 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 09:38:36-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 09:39:07 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 12:38:49 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 09:38:07 pdt
To: Gregor.pa@Xerox.COM
Cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: Name Change for Metaobject Protocol?
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 13 Oct 87 10:21:00 -0700.
<871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Wed, 14 Oct 87 09:38:03 MDT
Message-Id: <1709.561224283@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> The objects in the meta-object protocol are the objects which implement
> the (metacircular) evaluator. So the current name is just right.
OK, let it be then.
Gregor, we'll all be thinking of you during your operation. Good luck!
jak
∂14-Oct-87 1026 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Status (and TRACE-EXECUTION spec)
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:25:57 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 10:00:40-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 10:01:48 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 13:01:26 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 10:00:42 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Status (and TRACE-EXECUTION spec)
X-Mailer: mh6.5
In-Reply-To: Your message of 13 Oct 87 14:27:00 -0700.
Date: Wed, 14 Oct 87 10:00:36 MDT
Message-Id: <3026.561225636@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> LGD and I are working (like mad) on the spec. I am concentrating
> on the concepts chapter and Linda on the functions chapter.
> This will require very fast turnaround from you folks on the draft.
Ok, let us know if you need anything else.
I haven't posted an updated draft of the TRACE-EXECUTION generic function
yet, since it wasn't clear from the last meeting whether it was in
the same category as PRINT-OBJECT, and therefore should go in Section 2,
or was a Cleanup Committee issue. Clearly, the modifications to TRACE
are a Cleanup Committee issue. In any event, below is the text of the
TRACE-EXECUTION generic function spec I presented at the September meeting,
in case it should go in Section 2.
jak
Uppercase indicates BOLD, _this_ indicates italic
-------------------------------------------------------------------------------
TRACE-EXECUTION _object_ &KEY :ENVIRONMENT :BREAK _[Generic Function]_
TRACE-EXECUTION discriminates on _object_ to select an implementation
specific method that arranges for the executable entity associated
with _object_ to be traced. The :ENVIRONMENT keyword parameter is for
those implementations which require environmental information to
arrange for tracing to occur. Implementations are required to provide
TRACE-EXECUTION as the system level entry point for implementing TRACE
functionality. If the :BREAK keyword argument is not NIL, arrangement is
made for the BREAK function to be called after trace information is printed.
The exact nature and number of methods associated with TRACE-EXECUTION
will differ, depending on what executable entities can be specified
by TRACE, but every implementation needs to support methods which
dispatch on objects having the following classes:
SYMBOL-The function indicated by the symbol will be traced when invoked
in the environment.
METHOD-The method function is traced when invoked.
GENERIC-FUNCTION-The generic function is traced when the discriminator
code is invoked.
Implementations are encouraged to provide as many methods as is possible.
∂14-Oct-87 1029 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:29:08 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 14 Oct 87 10:14:08-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 14 Oct 87 10:15:01 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 14 Oct 87 13:14:44 edt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 14 Oct 87 10:14:03 pdt
To: dussud%jenner.csc.ti.com@csnet-relay.ARPA
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of Mon, 12 Oct 87 14:09:38 -0500.
<2770052978-7072022@Jenner>
Date: Wed, 14 Oct 87 10:14:00 MDT
Message-Id: <3277.561226440@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> In conclusion since I don't think the option is hard to understand or to
> explain and since any serious implementation will have to do something
> like that (at the sub-meta level at least), I think it is a good thing
> to standardize.
I pretty much agree with Danny and Gregor on this, and oppose adding
constructors. In addition, it is another DEFCLASS option, further
complicating the class creation language.
jak
∂14-Oct-87 1046 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: fixing our problems with setf
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Oct 87 10:46:35 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 255219; Wed 14-Oct-87 13:47:14 EDT
Date: Wed, 14 Oct 87 13:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: fixing our problems with setf
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871013-200700-6060@Xerox>
Message-ID: <19871014174716.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Tue, 13 Oct 87 20:01:00 PDT
From: Pavel.pa@Xerox.COM
A nit in your test case. It would be nicer if the optional variable end
had a default value rather than using the (unless end ...) hack:
Not so. Refer to the definition of the meaning of the arguments to functions
like subseq, CLtL p.246, which says that supplying NIL as end is the same as
omitting end.
;If setf of subseq was not already built into Common Lisp,
;it could have been defined like this
(defun (setf subseq) (new-value sequence start &optional (end (length
sequence)))
(setq end (min end (+ start (length new-value))))
(do ((i start (1+ i))
(j 0 (1+ j)))
((= i end) new-value)
(setf (elt sequence i) (elt new-value j))))
∂14-Oct-87 1620 DLW@ALDERAAN.SCRC.Symbolics.COM Name Change for Metaobject Protocol?
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 14 Oct 87 16:20:25 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 129525; Wed 14-Oct-87 17:19:30 EDT
Date: Wed, 14 Oct 87 17:18 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Name Change for Metaobject Protocol?
To: Gregor.pa@Xerox.COM, kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <871013102112.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871014211812.0.DLW@CHICOPEE.SCRC.Symbolics.COM>
Line-fold: No
The CLOS use of "meta-object" also seems right to me. I agree that
there would be some degree of confusion if we were presenting CLOS
primarily to an audience steeped in Smalltalk-80, which is what one
experiences at OOPSLA for the most part. But for the Lisp people, I
don't think the differences between our meta-objects and Smalltalk-80
metaclasses are a big enough problem to try to find some other
terminology.
∂16-Oct-87 0639 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 06:39:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 97363; Thu 1-Oct-87 12:40:09 EDT
Date: Thu, 1 Oct 87 12:40 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <22064.560102555@hplabsz>
Message-ID: <871001124004.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 01 Oct 87 10:02:35 MST
From: kempf%hplabsz@hplabs.HP.COM
Aren't these generic functions essentially doing the same thing?
No, because CLASS-CHANGED inherently involves two classes, but
UPDATE-OBSOLETE-INSTANCE inherently involves one class. They used
to do, and be, the same thing, before we simplified class redefinition
a couple of weeks ago.
Recall that CLASS-CHANGED methods can take advantage of abstractions,
rather than knowing about slots. Abstraction seems particularly
important when more than one class is involved.
∂16-Oct-87 0659 Moon@MEAD.SCRC.Symbolics.COM CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 06:39:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 97363; Thu 1-Oct-87 12:40:09 EDT
Date: Thu, 1 Oct 87 12:40 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <22064.560102555@hplabsz>
Message-ID: <871001124004.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 01 Oct 87 10:02:35 MST
From: kempf%hplabsz@hplabs.HP.COM
Aren't these generic functions essentially doing the same thing?
No, because CLASS-CHANGED inherently involves two classes, but
UPDATE-OBSOLETE-INSTANCE inherently involves one class. They used
to do, and be, the same thing, before we simplified class redefinition
a couple of weeks ago.
Recall that CLASS-CHANGED methods can take advantage of abstractions,
rather than knowing about slots. Abstraction seems particularly
important when more than one class is involved.
∂17-Oct-87 1157 RPG Constructors
To: common-lisp-object-system@SAIL.Stanford.EDU
I favor Moon's proposal.
-rpg-
∂18-Oct-87 2151 RPG The Results are In!
To: common-lisp-object-system@SAIL.Stanford.EDU
Here is the vote on dynamic versus indefinite extent of CALL-NEXT-METHOD:
Person Vote
-------------------------
Pavel dynamic
Dussud abstain
Gregor indefinite
Danny indefinite
Moon abstain (leans towards indefinite)
Kempf dynamic
Masinter dynamic
LGD dynamic
rpg abstain (leans towards dynamic)
Mlynarik indefinite
I think dynamic wins. Wny not say that CLOS specifies dynamic but that
a valid extension is indefinite?
-rpg-
∂19-Oct-87 0806 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The Results are In!
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 19 Oct 87 08:05:57 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 19 Oct 87 07:48:26-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 19 Oct 87 07:49:35 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 19 Oct 87 07:49:20 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 19 Oct 87 08:48:54 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: The Results are In!
X-Mailer: mh6.5
In-Reply-To: Your message of 18 Oct 87 21:51:00 -0700.
Date: Mon, 19 Oct 87 08:48:51 MDT
Message-Id: <28847.561653331@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
>
> I think dynamic wins. Wny not say that CLOS specifies dynamic but that
> a valid extension is indefinite?
fine.
jak
∂19-Oct-87 0900 Bobrow.pa@Xerox.COM initialize-instance on an exisiting instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:00:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 09:01:23 PDT
Date: 19 Oct 87 09:01 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: initialize-instance on an exisiting instance
To: common-lisp-object-system@SAIL.Stanford.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <871019-090123-6051@Xerox>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work. This would be a
way of reinitializing an instance. Is there any problem with this? I
would rather this be true than say "it is an error" to initialize an
instance more than once.
∂19-Oct-87 0932 Moon@YUKON.SCRC.Symbolics.COM initialize-instance on an exisiting instance
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:32:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278640; Mon 19-Oct-87 12:33:18 EDT
Date: Mon, 19 Oct 87 12:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: initialize-instance on an exisiting instance
To: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: <871019-090123-6051@Xerox>
Message-ID: <19871019163310.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 19 Oct 87 09:01 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work. This would be a
way of reinitializing an instance. Is there any problem with this? I
would rather this be true than say "it is an error" to initialize an
instance more than once.
Given what we said about permissible optimizations in initialize-instance, I
don't see how the semantics of this operation could be well-defined, unless
this isn't really the same initialize-instance that make-instance calls.
That might be reasonable: change "permissible optimizations in
initialize-instance" to "permissible optimizations in initialize-instance
when called by make-instance."
However, I'm not sure that calling initialize-instance on an existing
instance is going to be a particularly useful operation. Does it first
reset all the slots to uninitialized? Regular initialize-instance doesn't
do that. What if there are user-defined initialize-instance methods that
do such things as adding the instance to an auxiliary data structure? Can
they tolerate adding it twice? Or should one call a new function
deinitialize-instance before calling initialize-instance?
∂19-Oct-87 0951 Bobrow.pa@Xerox.COM Re: The Results are In!
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 09:51:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 09:51:47 PDT
Date: 19 Oct 87 09:51 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: The Results are In!
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 18 Oct 87
21:51 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-095147-6164@Xerox>
I think dynamic wins. Wny not say that CLOS specifies dynamic
but that a valid extension is indefinite?
Fine. I will bet that almost all implementations will be indefinite,
and users will get used to indefinite if it makes any difference. But I
think that dynamic will make a difference extremely rarely.
danny
∂19-Oct-87 1016 Bobrow.pa@Xerox.COM Re: initialize-instance on an exisiting instance
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 10:15:55 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 10:15:57 PDT
Date: 19 Oct 87 10:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: initialize-instance on an exisiting instance
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Mon, 19 Oct 87 12:33 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-101557-6220@Xerox>
Date: 19 Oct 87 09:01 PDT From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
We did not discuss this, but if a user calls
initialize-instance
on an existing instance, it seems that it should work.
This would be a way of reinitializing an instance. Is there
any problem with this? I would rather this be true than say
"it is an error" to initialize an instance more than once.
Given what we said about permissible optimizations in
initialize-instance, I don't see how the semantics of this
operation could be well-defined, unless this isn't really the same
initialize-instance that make-instance calls. That might be
reasonable: change "permissible optimizations in
initialize-instance" to "permissible optimizations in
initialize-instance when called by make-instance."
Either what I am asking makes sense, and it must be "permissible
optimizations in initialize-instance when called by make-instance.", or
what I am saying is nonsense, and the only place initialize-instance can
be called is make-instance, in which case "permissible optimizations in
initialize-instance" is the same as "permissible optimizations in
initialize-instance when called by make-instance."
However, I'm not sure that calling initialize-instance on an
existing instance is going to be a particularly useful operation.
Does it first reset all the slots to uninitialized? Regular
initialize-instance doesn't do that. What if there are
user-defined initialize-instance methods that do such things as
adding the instance to an auxiliary data structure? Can they
tolerate adding it twice? Or should one call a new function
deinitialize-instance before calling initialize-instance?
I think users who cause side effects in initialization should be aware
of them. But otherwise one would want the effect to be as though you
had just allocated a new instance, except that one has an instance eq to
the original. We have had some Loops users who have used a feature
like this. But the problems you mention are real, and it was why I sent
out my query.
Perhaps, a simpler way of providing for this purpose would be to provide
a generic-function (copy-slot-contents from to) whose default behavior
for instances of the same class is to copy the contents (incuding
unbound slots). Or should this be only a function that signals an error
when the classes of the two instances are not the same? Or is this too
esoteric an application to be included in the standard. In any event,
we must make a statement about initialize-instance, and how many times
it can be called (and from where?).
∂19-Oct-87 1826 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 18:26:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 OCT 87 18:18:13 PDT
Date: 19 Oct 87 18:18 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 17 Oct 87
11:57 PDT
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871019-181813-1026@Xerox>
If we are voting, I prefer leaving it out of the standard for now.
danny
∂20-Oct-87 0926 RPG Constructors
To: common-lisp-object-system@SAIL.Stanford.EDU
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance. Using the Principle
of Insignificant Degradation and Occam's Chainsaw, I don't think that
make-instance and constructors burden the user with too many ways to
do things, given that one is an abstraction mechanism.
-rpg-
∂20-Oct-87 1028 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Oct 87 10:28:31 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 OCT 87 10:28:25 PDT
Date: 20 Oct 87 10:28 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 20 Oct 87
09:26 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871020-102825-1807@Xerox>
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance. Using the Principle
of Insignificant Degradation and Occam's Chainsaw, I don't think
that make-instance and constructors burden the user with too many
ways to do things, given that one is an abstraction mechanism.
The abstract interfaces are functions that the user can write, with very
few extra characters. Occam's chainsaw cuts off extra mechanism when it
serves no real purpose. The extra syntax in defclass, the functions to
make constructors, etc are all extra baggage
One compares:
(defclass foo ()
(a b)
(:constructor make-foo))
with
(defclass foo ()
(a b))
(defun make-foo (initargs)
(make-instance 'foo initargs))
And then if the user decides to have make-foo do some additonal work,
there is appropriate place to put the code.
∂20-Oct-87 1033 skeene@STONY-BROOK.SCRC.Symbolics.COM Constructors
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Oct 87 10:33:10 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 259181; Tue 20-Oct-87 13:34:06 EDT
Date: Tue, 20 Oct 87 13:34 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Constructors
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 20 Oct 87 12:26 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871020173404.8.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: 20 Oct 87 0926 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The argument I buy for having constructors is that they provide
a more abstract interface than make-instance.
This argument appeals to me as well. I vote in favor of constructors.
∂20-Oct-87 1923 Pavel.pa@Xerox.COM The extent of CALL-NEXT-METHOD (a retraction)
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Oct 87 19:23:07 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 20 OCT 87 19:23:50 PDT
Date: Tue, 20 Oct 87 19:23:36 PDT
From: Pavel.pa@Xerox.COM
Subject: The extent of CALL-NEXT-METHOD (a retraction)
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <871020-192350-2853@Xerox>
Well, I had a conversation with Danny about this issue. He brought up
the following example, which I find compelling enough to justify
switching my ``vote'' from `dynamic' to `indefinite'.
Suppose we pick the `dynamic' extent. Suppose that you've got a piece
of code in some method that includes an FLET'd function and suppose
further the method returns said function as its value. This is fine, it
should work, we've all probably done something like it a dozen times.
However, if you've got a call to CALL-NEXT-METHOD inside that FLET'd
function, then it doesn't work, something awful happens, we'll all get
bit by it a dozen times and curse our short-sightedness.
I can't off-hand come up with an example of something else in Common
Lisp that I have to be careful of, except for things that I already find
it intuitive to worry about: special variables, condition handlers,
CATCH phrases, etc. The function CALL-NEXT-METHOD is not obviously
`dynamic'; I therefore predict that I (and many other programmers) will
fail to remember that it IS `dynamic' and that we will therefore make
such mistakes many times before we learn.
It is, of course, no consolation that many (most? probably not all)
implementations will, in fact, allow indefinite extent. That simply
means that I won't realize my mistake until I'm porting my code to the
one implementation that met the spec exactly.
So, as I said above, consider this a change of my ``vote''.
Pavel
∂21-Oct-87 0835 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: The extent of CALL-NEXT-METHOD (a retraction)
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 08:34:58 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 08:33:24-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 08:33:38 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 08:33:15 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 09:32:48 pdt
To: Pavel.pa@Xerox.COM
Cc: Common-Lisp-Object-System@SAIL.Stanford.Edu
Subject: Re: The extent of CALL-NEXT-METHOD (a retraction)
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 20 Oct 87 19:23:36 -0700.
<871020-192350-2853@Xerox>
Date: Wed, 21 Oct 87 08:32:45 PDT
Message-Id: <23704.561828765@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Suppose we pick the `dynamic' extent. Suppose that you've got a piece
> of code in some method that includes an FLET'd function and suppose
> further the method returns said function as its value. This is fine, it
> should work, we've all probably done something like it a dozen times.
> However, if you've got a call to CALL-NEXT-METHOD inside that FLET'd
> function, then it doesn't work, something awful happens, we'll all get
> bit by it a dozen times and curse our short-sightedness.
I didn't buy this argument when I first heard it, and I don't buy it
now.
FLET and CALL-NEXT-METHOD are two different things. The definition of
a locally defined function must be lexically visible inside the definition
of FLET. That is, after all, the function of FLET. Thus, if the lexically
defined function is thrown out of the scope of the FLET, arrangement for
calculation of a closure over the lexical environment can be made at compile
time. The definition of CALL-NEXT-METHOD, on the other hand, is not lexically
precisely determined at all. Within a particular lexical scope,
CALL-NEXT-METHOD is defined to call the "next" method. Precisely what the
"next" method is will be determined by the parameters of the generic
function invocation, during the effective method calculation. In general,
these can only be determined at run time, thus the definition of
CALL-NEXT-METHOD is determined dynamically, and the compiler cannot form a
closure if the CALL-NEXT-METHOD leaks out of scope. In specific instances
it may be possible to optimize out the run time calculation, but that
should not be of concern in specifying CALL-NEXT-METHOD does.
So, for CALL-NEXT-METHOD to become indefinite in extent, Common Lisp needs the
addition of dynamic closures. Other languages (and some extensions of
Common Lisp) have these-they're called "coroutines" or "lightweight processes".
These take a closure over varying aspects of the dynamic state of the
program. In the case of CALL-NEXT-METHOD, the amount of state which would
need to be saved may not be as much as in the case of a coroutine, but
the principle is the same.
Since this would be the only case of taking a dynamic closure in Common
Lisp, I think we should stick with dynamic extent.
jak
∂21-Oct-87 0848 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 08:47:56 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 08:46:48-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 08:45:48 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 08:45:27 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 09:44:58 pdt
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of 20 Oct 87 09:26:00 -0700.
Date: Wed, 21 Oct 87 08:44:55 PDT
Message-Id: <23800.561829495@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> The argument I buy for having constructors is that they provide
> a more abstract interface than make-instance. Using the Principle
> of Insignificant Degradation and Occam's Chainsaw, I don't think that
> make-instance and constructors burden the user with too many ways to
> do things, given that one is an abstraction mechanism.
I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in abstraction.
Most programmers will want to name their constructors in a way which
is reflective of their function, to construct a particular class. Thus,
if they change the class name, it would make sense to change the
constructor name, so that the name continues to reflect the function.
Whether they change a constructor function name or a class name in
a MAKE-INSTANCE form makes little difference. Thus, for the price of
yet another DEFCLASS construct, you get very little in the way of
additional abstraction. And, as has been argued, programmers who
want to do this will do it anyway. Most programmers are going to
want to do things like:
(defun make-bar-foo (widgits)
(make-instance 'foo :name 'bar :number-of-widgits widgits))
and constructors won't help there. Or, if they could, the addition to
the DEFCLASS syntax wouldn't be worth the savings in not having to define
the constructor seperately.
The only argument I find vaguely attractive is the optimization one,
though I suspect this is probably more of an issue on dedicated hardware
than on general purpose machines. However, since the general Common Lisp
method of specifying optimizations is using the DECLARE construct, I
think any attempt to optimize instance construction should go that route.
I therefore vote "NO" on Measure C.
jak
∂21-Oct-87 0956 Moon@STONY-BROOK.SCRC.Symbolics.COM indefinite extent of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Oct 87 09:56:26 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260036; Wed 21-Oct-87 12:57:27 EDT
Date: Wed, 21 Oct 87 12:57 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: indefinite extent of call-next-method
To: Common-Lisp-Object-System@sail.stanford.edu
References: <871020-192350-2853@Xerox>,<23704.561828765@hplabsz>
Message-ID: <19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Pavel is right, of course.
I don't find Jim's argument convincing at all. To my mind,
call-next-method is a function that is closed over the identity
of the next method and the arguments to be passed to it, just
as a function defined by labels with a free reference that is
captured in an outer scope is closed over the variable in the
free reference. In both cases it's equally true and equally
irrelevant to the scope of the closure that the value of the
closed-over variable is only known at run time.
∂21-Oct-87 1000 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM TRACE Proposal
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 21 Oct 87 10:00:21 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 21 Oct 87 09:58:54-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 21 Oct 87 09:59:19 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 21 Oct 87 09:58:43 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 21 Oct 87 10:58:12 pdt
To: Masinter.pa@Xerox.com
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: TRACE Proposal
X-Mailer: mh6.5
Date: Wed, 21 Oct 87 09:58:09 PDT
Message-Id: <24566.561833889@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Larry:
Here is a copy of the proposed modifications to TRACE, which
were discussed at the September CLOS committee meeting. I have not
included the TRACE-EXECUTION proposal, since it is a generic function,
similar to PRINT-OBJECT, and its disposition was not clear at the
meeting.
I hope this gets to you in time for the November meeting. If
not, apologies: OOPSLA and recovery took longer than expected.
Jim Kempf
-------------------------------------------------------------------------------
Issue: TRACE-CLOS
References: trace macro pp. 440-441
Category: MODIFICATION
Edit history: Version 1, 21-Oct-87 Kempf
Problem description:
With the addition of the Common Lisp Object System, there is no
command language level way to trace individual method execution.
The TRACE macro, as currently specified in Common Lisp, allows
only tracing of globally defined functions through their names.
Since a generic function name may have several executable methods,
users need some way to specify that they would like invocation of particular
methods to be traced, rather than invocation of the entire generic
function.
In addition, the current specification of TRACE does not allow tracing
of functions associated with SETF "methods", of macro functions,
nor of lexically defined functions or functions invoked via. their
function definition objects. While this proposal does not attempt
to address the latter problems, since identification and/or tracing of these
is likely to be implementation dependent, it does leave
open the option for those implementations which can arrange it. Finally,
some implementations of Common Lisp have extended TRACE to take an option
which puts the system into a break loop after the trace information has been
printed. This proposal adds that capability to the standard.
Proposal (TRACE-CLOS::TRACE-FUNCTION-SPECIFICATION)
(Font Note: UPPERCASE indicates bold, _this_ indicates italic)
TRACE _function-spec_ &KEY (:BREAK NIL) _[Macro]_
TRACE
UNTRACE _function-spec_ _[Macro]_
UNTRACE
Invoking TRACE with a function specification causes the function specified
to be traced. Henceforth, whenever the specified function is invoked,
information about the call, the arguments passed, and the returned
values, if any, will be printed to the stream that is the value of
*TRACE-OUTPUT*. If the keyword argument :BREAK is T, then the BREAK
function will be called after the trace information is printed.
UNTRACE undoes any tracing. Calling TRACE without any arguments
prints a list of currently traced executable entities, calling
UNTRACE without any arguments causes tracing to be undone for
all currently traced entities.
A _function_spec_ is either a symbol naming a function (i.e. a
symbol whose global function cell is bound to a function definition
object, or to which the application of MACRO-FUNCTION will return
a function definition object) or a list whose first element indicates
what kind of funcallable object is to be traced and whose tail indicates
which particular function should be traced. The complete set of
function specifications will necessarily be implementation dependent; however,
every implementation is required to support the following:
_symbol_-Invocations of the function or macrofunction named by
_symbol_ via. _symbol_ as a global name are traced.
(METHOD _generic-function-name-specification_
_{method-qualifiers}_*
_parameter-specializer-name-list_
)
If the method whose parameter specializer list, generic function
name specification, and method qualifiers are listed is tracable,
then invocations through the generic function name specification
will be traced.
(SETF _symbol_)-If the SETF function having the name specification
is tracable, it will be traced (see proposal SETF-CLOS for
more information on SETF name specifications).
Implementations are encouraged to provide for tracing of as many
funcallable objects as possible.
Rationale:
Adoption of the Common Lisp Object System will require the availability
of debugging information on individual methods.
Current practice:
Some Common Lisp implementations have extended TRACE syntax to
allow specification of breaks. Currently, the TRACE macro is
specified to take any number of symbols.
Adoption Cost:
The syntax of the TRACE macro will take only one function specification
in order to accomodate the :BREAK key. But, since TRACE tends to
be used interactively at the command langauge level, the impact
on existing code should be slight.
Cost of non-adoption:
Without this, implementation dependent ways of specifying the
:BREAK option would continue to be used. In addition, most
implementors would probably add their own syntax for allowing
programmers to obtain information on individual method invocation.
Benefits:
Allow programmers to obtain information on individual method
invocations.
Conversion Cost:
Minor re-write of the TRACE and UNTRACE macros.
∂21-Oct-87 1032 RPG The Latest Draft
To: common-lisp-object-system@SAIL.Stanford.EDU
The latest drafts for chapters 1, 2, and 3 are to be found in the files
concep.tex
functi.tex
mopfun.tex
on [cls,lsp]. The file tex.ins tells how to TEX these files.
Moon, Sonya, Danny, and Gregor are currently proofreading the drafts,
and LGD and I will spend most of our cycles servicing their comments,
but you should feel free to read them and comment.
-rpg-
∂21-Oct-87 1114 Gregor.pa@Xerox.COM indefinite extent of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Oct 87 11:14:16 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 21 OCT 87 11:12:29 PDT
Date: Wed, 21 Oct 87 11:12 PDT
From: Gregor.pa@Xerox.COM
Subject: indefinite extent of call-next-method
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871021111207.2.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Moreover, as I have tried to say before, I am pretty sure that people
reading the how method combination works stuff would naturally assume
indefinite extent since the behavior described there inherently is what
Moon described as:
Date: Wed, 21 Oct 87 12:57 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
To my mind,
call-next-method is a function that is closed over the identity
of the next method and the arguments to be passed to it, just
as a function defined by labels with a free reference that is
captured in an outer scope is closed over the variable in the
free reference. In both cases it's equally true and equally
irrelevant to the scope of the closure that the value of the
closed-over variable is only known at run time.
-------
∂21-Oct-87 1254 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 21 Oct 87 12:54:22 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab17113; 21 Oct 87 15:34 EDT
Received: from csl.ti.com by RELAY.CS.NET id ad22000; 21 Oct 87 15:31 EDT
Received: from Jenner by tilde id AA07478; Wed, 21 Oct 87 13:53:45 CDT
Message-Id: <2770829823-15823760@Jenner>
Date: Wed, 21 Oct 87 13:57:03 CDT
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: kempf%hplabsz@hplabs.hp.com
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of Wed, 21 Oct 87 08:44:55 PDT from kempf%hplabsz@hplabs.hp.com
I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
The difference is the same as between
(send object :do-this ) and (do-this object).
Most programmers will want to name their constructors in a way which
is reflective of their function, to construct a particular class. Thus,
if they change the class name, it would make sense to change the
constructor name, so that the name continues to reflect the function.
Whether they change a constructor function name or a class name in
a MAKE-INSTANCE form makes little difference. Thus, for the price of
yet another DEFCLASS construct, you get very little in the way of
additional abstraction. And, as has been argued, programmers who
want to do this will do it anyway. Most programmers are going to
want to do things like:
(defun make-bar-foo (widgits)
(make-instance 'foo :name 'bar :number-of-widgits widgits))
You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration, which is
another advantage over a separate constructor function.
and constructors won't help there. Or, if they could, the addition to
the DEFCLASS syntax wouldn't be worth the savings in not having to define
the constructor seperately.
The only argument I find vaguely attractive is the optimization one,
though I suspect this is probably more of an issue on dedicated hardware
than on general purpose machines. However, since the general Common Lisp
method of specifying optimizations is using the DECLARE construct, I
think any attempt to optimize instance construction should go that route.
I don't think that the value of the constructor option as an aid to
optimization has anything to with the architecture of the machine. On
any architecture, if you implement MAKE-INSTANCE by interpreting the
various data structures (initargs list, default initargs), it is going
to be costly. You will need a mechanism to generate some specialized
code reflecting the interpretation for a particular class. If we don't
standardize the mechanism, every implementation will do it its own way,
including the programmer tinkering with metaclasses. I is better to
agree one a general mechanism. That's what the second part of Moon's
proposal is all about.
And I reiterate my "YES".
Patrick.
∂21-Oct-87 1649 Bobrow.pa@Xerox.COM Re: Constructors
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Oct 87 16:49:22 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 OCT 87 16:44:26 PDT
Date: 21 Oct 87 16:39 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Constructors
In-reply-to: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>'s
message of Wed, 21 Oct 87 13:57:03 CDT
To: DUSSUD%jenner.csc.ti.com@RELAY.CS.NET
cc: kempf%hplabsz@hplabs.hp.com,
common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871021-164426-4161@Xerox>
jak: I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
pd The difference is the same as between
(send object :do-this ) and (do-this object).
I don't understand the analogy at all.
pd You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration,
which is another advantage over a separate constructor function.
1) How does the &aux get added to the argument list of a constructor?
How does this do what jak asked for?
2) This option is not textually close to any inherited initarg
declarations. The fact that it is close to some and not all has large
confusion potential.
On any architecture, if you implement MAKE-INSTANCE by
interpreting the various data structures (initargs list, default
initargs), it is going to be costly. You will need a mechanism to
generate some specialized code reflecting the interpretation for a
particular class.
This is clearly a good thing.
The question it is better to focus it on calls to make-instance, or is
it better to combine this optimization with an automatic function
generation facility, with other features? The former seems like the
"general mechanism" to me (pd says "I think it is better to
agree one a general mechanism.")
∂21-Oct-87 2033 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM First round of comments on the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Oct 87 20:33:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 260598; 21 Oct 87 23:34:23 EDT
Date: Wed, 21 Oct 87 23:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: First round of comments on the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022033419.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the 20 Oct 1987 16:34 draft of the CLOS documentation
pages 1-1 through 1-32.
I don't think we need the concept of "setf generic function" at all
any more. Such generic functions are now completely the same as
ordinary generic functions except that you get to them through
SYMBOL-FUNCTION of a name that is a list. I don't think we need
special mention of "setf generic functions" all over the place.
I would just say in the paragraph on 1-21 that begins "In Common
Lisp, a name can be given to a function...", something like
the following: "The name of a generic function, like the name of
an ordinary function, can be either a symbol or a two-element
list whose first element is {\bf setf} and whose second element
is a symbol. This is true for both local and global names."
The section "Introduction to Setf Generic Functions" can be completely
eliminated. If we want to publicize the recent cleanup that introduced
setf functions, we can attach that as an appendix; in any case, I think
this is better explained without reference to generic functions.
1-8 bottom of page: change two references to "setf method" to
"a method for writing the value of the slot", and then after
"appropriate generic functions" say the reading generic function
has a name specified in the defclass, while the writing generic
function is named (setf -reader-).
1-25 second paragraph: We don't need to make any distinction about
setf generic functions here; delete the paragraph.
================
The section title "Changing Classes" is poor. We aren't doing
anything to a class, we're doing something to an instance. A
more appropriate title would be "Changing the Class of an Instance".
================
We need to put in the glossary.
================
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
================
1-6 fourth paragraph: Clarify the range of n in the definition of
"superclass". I think you mean n >= 2, so that any "direct superclass"
is also a "superclass", but a class is not a superclass of itself.
================
1-8 bottom of page: "When a reader or accessor is specified for an
individual slot...": I don't understand what "individual" is in contrast to.
Every reader or accessor is for one slot, we don't have anything that
reads several slots and returns multiple values or anything like that.
If this sentence is just left over from the removal of :accessor-prefix,
we can just delete the sentence.
================
1-11 third bullet: we could just say "... union of the initialization
arguments declared in :initarg slot options in all the slot specifiers."
since all these bullets assume a set of slot specifiers for one name.
================
1-11 last sentence: needs to be updated with a correction I sent earlier,
because :default-initargs can appear more than once in a defclass.
================
1-15 last paragraph: It might be worth mentioning that the copy has dynamic
extent. This is mentioned in the remarks on 2-13, but it might be worth
repeating here.
================
1-16 fourth paragraph last sentence: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion of
a standard type class as a superclass of a class."
================
1-18 last sentence: Actually a loop can contain more than two classes.
================
1-19 third paragraph last sentence: "will be followed by all classes
in T1", append "except t". The example could actually be generalized
to a join class J that isn't t, provided none of J's superclasses
appear elsewhere in the graph than above J. Then we have T1 up to
but not including J, followed by T2, ending in J and its superclasses.
================
1-23 last bullet: "(EQL -object-)" should be "(EQL -form-)", because
in a parameter specializer name, we have a form that is to be evaluated
to produce the object that appears in the parameter specializer. The
paragraph immediately following is wrong where it says "otherwise N
equals P" for this reason. We changed this when we changed QUOTE to EQL.
1-23 fourth paragraph: We no longer require parameter specializer names
to be Common Lisp type specifiers. (EQL -form-) is not a type-specifier.
================
1-23 last paragraph: I think the reference to make-instance here should
be changed to say specifically "make-instance of standard-method".
================
1-24 last paragraph: It's no longer true in the short form of
define-method-combination that primary methods can be unqualified.
Now, primary methods are qualified with the name of the type of
method combination, while auxiliary methods are qualified with :around.
================
1-32 first sentence: generic-flet, generic-labels, and with-added-methods
also accept a :method-combination argument.
================
1-32 first bullet last sentence: I don't understand why the word "only"
is present here. Maybe you mean "is supported only in :around methods
when a built-in" rather than "is supported in :around methods only when
a built-in"; i.e. does "only" modify ":around methods" or does it modify
"when"? Also, this sentence should probably be pulled out of the bullet
since I think it is saying something about both method roles. Maybe the
sentence should be deleted since the same information is repeated later
on the page.
================
OPEN ISSUES:
1-13 fourth paragraph: I think slot reinitialization should not be done
by a method for update-instance-structure. Instead it should be done at
the meta-object level, and defined to be completed before
update-instance-structure is called. This would be consistent with
change-class.
1-16 second paragraph: The specification about type-of here only applies
to instances of standard classes, or something like that. It certainly
doesn't apply to instances of all standard type classes. (Boy the
distinction between "standard class" and "standard type class" is
confusing! The two names always sound the same to me.)
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
================
TYPOS:
1-7 bottom of page: "the generic function uninitialized-slot" should be
"the generic function slot-unbound".
1-9 last sentence: "invokes the function slot-value is to", "is" is
a typo.
1-15 third sentence: "When an instance is updated", "updated" should be
"changed".
1-15 fifth paragraph: Delete the whole paragraph, this was accidentally
copied from the "redefining classes" section.
1-19: "(food t)" should be "(food, t)" in two places. 1-20 also.
1-22 third paragraph: "defintions"
1-22: "a names of the form (setf name)"
1-22: "Consider setf form (setf ..." should be "Consider the form (setf ...".
1-23 first line: We haven't defined the term "setf macro". Could say
"a setf macro defined for name with defsetf or define-setf-method".
1-23 in the funcall: "#:temp-2" should be "#:temp-1".
1-25 bullet 4 last sentence: "in in" should be "in".
1-25 Section "Named Arguments...": In this section's title and text,
"named argument" should be "keyword argument". My fault: I forgot to
mail out a corrected version of this section when the terminology
was changed back.
∂22-Oct-87 0837 skeene@STONY-BROOK.SCRC.Symbolics.COM My comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 08:37:41 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260872; Thu 22-Oct-87 11:38:42 EDT
Date: Thu, 22 Oct 87 11:36 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: My comments on Chapter 1
To: rpg@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19871022153612.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
In general, the spec seems to be coming together nicely. I think it
reads better than it used to, and the tone is quite consistent
throughout.
----------------
I found it somewhat distracting that hyphenated functions are split
across lines.
1-7, second group of bullets, bullet #2:
"appropriately named" should be deleted; it implies that there is a
heuristic that makes up an appropriate name for the accessor generic
functions.
1-7, second to last paragraph
Fix typo "unitialized". Actually, I suggest deleting the sentence
containing the typo. The sentence is: "When an uninitialized slot is
read, the generic function uninitialized-slot is invoked." That's too
much detail for the overview; it bypasses describing the default
behavior, which would be more appropriate for an overview. In any
case, I believe the previous sentence is sufficient.
1-10, second paragraph under "Inheritance of Slots and Slot Options"
The last clause says "all instances of C access that single slot"; I
suggest saying instead "all instances of C can access that single slot"
or "that single slot is accessible to all instances of C."
1-13, regarding the default method for update-instance-structure
I like Moon's suggestion that the default method doesn't do the work.
But if that suggestion is not accepted, we should mention that users
should write after-methods unless they want to prevent the default
method from occurring. This could go at the end of the fourth
paragraph. Also it would be better to move the sentence beginning
"Methods for update-instance-structure can be defined..." from the 3rd
paragraph to the 4th, where the rest of the discussion about writing
methods is.
1-15
I agree with Moon that a better name is "Changing the Class of an
Instance". I also think it's confusing to use the terminology "old
class" and "new class" here, because the terms are used very differently
in the previous section. In the previous section "old class" meant
"that class that is now obsolete". Here it means "the previous class
of the instance". Here the "old class" is still current; it isn't
obsolete. I think new terminology could make it more clear what the
difference is between "changing the class of an instance" and
"redefining a class" -- how about using C-1 and C-2 terminology. That
makes it more clear that C-1 is not "old" or "obsolete" in any way; it's
just a class like any other.
Last paragraph: add "The default primary method for class-changed does
nothing." near the end of the paragraph.
1-17, Figure 1-1
The column header "Superclasses" doesn't make it clear that the order of
these classes is from most to least specific. In my draft of this the
column header was "Class Precedence List", which did make this clear.
1-19, First Example
Should state explicitly that the goal is to determine the CPL for the
class pie.
1-21, 3rd paragraph
"Ordinary functions and generic functions are called with identical
syntax." I can't remember for sure, but I believe we decided that
generic functions must have at least one required argument. If so,
this is one (minor) syntactic difference between ordinary and generic
functions.
1-21, 4th paragraph
Last sentence implies you need to evaluate a set of forms (a set of
defmethods and possibly a defgeneric) to produce a generic function
object, whereas really the evaluation of only one such form would do it.
1-21, last sentence
What is meant by "defgeneric (etc) are said to define a generic
function"? Unless you define "define", this is too vague to mean
anything. And if "define" means "create a g-f object", then defmethod
ought to be mentioned too.
1-22, second paragraph, last sentence
Regarding exporting names of generic functions from packages, the clause
"if it is part of an external interface" implies there is a way to
actually specify an external interface. I suggest replacing that
phrase with "if desired".
1-22, fifth paragraph, last sentence
I suggest replacing "The lambda-list of the generic function is defined
to be congruent with the lambda-list of the new method." with "The
lambda-list of the generic function is derived from the lambda-list of
the new method"
1-22, second to last paragraph
Typo: "specifying a names of"
1-25, second to last paragraph
"it is rare to find a vector used as a qualifier" -- The tone of this
clause is inconsistent with the usual factual, dry tone of the spec.
Since it doesn't add anything to what was already said, we should delete
it.
1-26, last paragraph
Change "not by all methods" to "not by all methods for the generic
function".
1-29, last paragrpah
Split up this too-long sentence into two or more sentences.
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because it
is the default doesn't mean that it shouldn't have a name.
1-31
We don't say here what happens if a generic function is called and
there is no applicable method at all. Presumably an error is signaled.
1-32, first bullet, last sentence
Replace this sentence with "Use of the function call-next-method is
supported in :around methods."
1-32, second bullet
Add this sentence "Use of the function call-next-method is not
supported in primary methods."
1-32, third paragraph (excluding bullets)
It looks weird to have the close paren alone on the line. Bad line
break.
∂22-Oct-87 0842 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 22 Oct 87 08:42:05 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 22 Oct 87 08:40:52-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Thu, 22 Oct 87 08:42:21 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 22 Oct 87 08:41:56 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 22 Oct 87 09:41:28 pdt
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@sail.stanford.edu
Subject: Re: indefinite extent of call-next-method
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 21 Oct 87 12:57:00 -0400.
<19871021165723.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 22 Oct 87 08:41:18 PDT
Message-Id: <7120.561915678@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> I don't find Jim's argument convincing at all. To my mind,
> call-next-method is a function that is closed over the identity
> of the next method and the arguments to be passed to it, just
> as a function defined by labels with a free reference that is
> captured in an outer scope is closed over the variable in the
> free reference. In both cases it's equally true and equally
> irrelevant to the scope of the closure that the value of the
> closed-over variable is only known at run time.
The difference is that the name of the free reference in the case of a function
defined by LABELS or FLET is lexically apparent, while the identity
of the next method and arguments to be passed for CALL-NEXT-METHOD are not.
This means that a programmer trying to understand program structure for a
function defined by labels or FLET need only look at the source where the
function is passed out of scope, while, with CALL-NEXT-METHOD, the programmer
must run the code. In the case of the function, the values are dynamically
determined but the control structure is not, modulo function valued variables.
In the case of CALL-NEXT-METHOD, the control structure is dynamically
determined. Anticipating the question of "how does this differ from generic
functions or a direct call to CALL-NEXT-METHOD", in both these cases there
are lexical cues that control structure is dynamically calculated. In the
case of a generic function invocation, it is the name of the generic
function, for which the application of SYMBOL-FUNCTION will return a
generic function object. In the case of CALL-NEXT-METHOD, it is the lexical
context of a method definition. An executable entity enclosing a
CALL-NEXT-METHOD passed out of scope could be any one of a number of
things, some of which will give no clue that they enclose a CALL-NEXT-METHOD.
I understand your and Pavel's concern, however, I have a couple of problems
with this. I think it is important that the implications of making
CALL-NEXT-METHOD indefinite in extent be outlined up front, rather than
having implementors duplicate the discussion we've been going through.
This has been the case for other new concepts we've introduced, such as
generic functions. The other problem is one of design philosophy, which
is, of course, open to debate. I believe that it is usually a good idea
to offer people an "economy" option and a "luxury" option. Although
it's always dangerous to say what "most" people do, I think most
programmers won't be affected if CALL-NEXT-METHOD is implemented either
way. On the other hand, I can imagine certain "economy" CL implementations
in which implementing CALL-NEXT-METHOD as having indefinite extend may
be difficult, or adversely impact use of CALL-NEXT-METHOD in some manner.
Thus Dick's solution of specifying dynamic extent (as the "economy" option)
with "indefinite" as an allowable extention (as the "luxury" option)
appeals to me.
jak
∂22-Oct-87 1037 Moon@STONY-BROOK.SCRC.Symbolics.COM Rest of comments on chapter 1 of the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 10:37:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260975; Thu 22-Oct-87 13:38:45 EDT
Date: Thu, 22 Oct 87 13:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Rest of comments on chapter 1 of the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022173842.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments on the 20 Oct 1987 16:34 draft of the CLOS documentation
pages 1-33 through 1-39.
1-33 second bullet: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion of
a standard type class as a superclass of a class."
(same issue as 1-16).
1-33 second bullet second sentence: I would delete the word "user-defined",
as on p.1-16, or change it to "defclass-defined."
1-33 second bullet last sentence: Remove this, we finished figuring out
which CL types have corresponding classes.
================
1-33 last bullet: Do generic-flet, generic-labels, generic-function, and
with-added-methods use standard-generic-function as the default class of
the generic function they define? I think they do.
================
1-33 last sentence: CLOS provides several predefined method combination
types, so I would change this sentence to refer to method combination
types in general not having their own meta-objects, rather than specifically
mentioning the standard method combination type. But see open issue below.
================
1-34 through 1-39: I had already reviewed this section before, but I
read it again carefully. It's almost all okay.
1-35 second paragraph: Maybe "both purposes" would be better than
"more than one purpose", since "more than one" made me think there were
more than the two purposes listed and maybe I had missed something.
1-37 first line: I'd say "It is not recommended that :initform forms
or default value forms have side-effects other than creating new objects."
since some people consider allocating storage to be a side-effect.
1-39 last line: "approved" might be a better word than "validated", since
we are trying to imply that check-initargs would definitely not signal
an error for the default initialization arguments and therefore does
not need to see them.
================
OPEN ISSUES:
1-33 last sentence: Just the other day I had to put a kludge into a
Flavors tool, instead of doing something elegant, due to the fact that
in Flavors there are no meta-objects for method-combination types. In
this case, I wanted to know what the qualifiers for primary methods
were. Perhaps when the meta-object protocol is a bit more clearly
defined, we can add meta-objects for method-combination types, so that a
method-combination type can specialize the behavior of more functions
than just compute-effective-method.
================
TYPOS:
1-36 fifth paragraph second line: "to a produce a"
1-38 last bullet: The section name in the cross-reference is spelled slightly
differently here than on the previous page.
∂22-Oct-87 1103 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com Re: Constructors
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:03:30 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae28458; 22 Oct 87 12:32 EDT
Received: from csl.ti.com by RELAY.CS.NET id ab28599; 22 Oct 87 12:30 EDT
Received: from Jenner by tilde id AA17681; Thu, 22 Oct 87 10:11:42 CDT
Message-Id: <2770902739-3696863@Jenner>
Date: Thu, 22 Oct 87 10:12:19 CDT
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: kempf%hplabsz@hplabs.hp.com, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
In-Reply-To: Msg of 21 Oct 87 16:39 PDT from Danny Bobrow <Bobrow.pa@xerox.com>
Date: 21 Oct 87 16:39 PDT
From: Danny Bobrow <Bobrow.pa@xerox.com>
Subject: Re: Constructors
jak: I don't think the difference between;
(make-foo :name 'bar :number-of-widgits 50)
and:
(make-instance 'foo :name 'bar :number-of-widgits 50)
is sufficiently large to constitute a useful addition in
abstraction.
pd The difference is the same as between
(send object :do-this ) and (do-this object).
I don't understand the analogy at all.
If the interface to my program is a bunch of SEND messages, I expose (to
my user)the fact that I am using object programming. Sometimes this is
fine, sometimes I want to be more abstract. Generic functions give me
this abstraction. If the consing interface of my program is a bunch of
MAKE-INSTANCE, I expose the fact that I am using object programming. In
this sense, a constructor function gives me an abstraction for consing,
like generic functions give me the abstraction for programming.
pd You do that by adding the following option in the defclass:
(:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
This option is textually close to the initargs declaration,
which is another advantage over a separate constructor function.
1) How does the &aux get added to the argument list of a constructor?
How does this do what jak asked for?
I am including the relevant part from Moon's proposal:
Each parameter supplies the value of
one initarg, determined by the following rules:
- If a parameter variable name is EQ to an initarg name, the parameter
supplies the value of that initarg.
- If a parameter variable name is not EQ to any initarg name, but the symbol
in the keyword package with the same name as the parameter variable
name is EQ to an initarg name, the parameter supplies the value of that
initarg.
- If neither rule succeeds, signal an error.
The second rule exists because initarg names are often keyword symbols, which
are not valid as variable names.
-constructor-lambda-list- allows all of the standard lambda-list features that
DEFUN allows.
2) This option is not textually close to any inherited initarg
declarations. The fact that it is close to some and not all has large
confusion potential.
It is not more confusing that the :DEFAULT-INITARGS option, and
certainly less than a separate constructor definition.
On any architecture, if you implement MAKE-INSTANCE by
interpreting the various data structures (initargs list, default
initargs), it is going to be costly. You will need a mechanism to
generate some specialized code reflecting the interpretation for a
particular class.
This is clearly a good thing.
The question it is better to focus it on calls to make-instance, or is
it better to combine this optimization with an automatic function
generation facility, with other features? The former seems like the
"general mechanism" to me (pd says "I think it is better to
agree one a general mechanism.")
I see moon's proposal being a good combination of desirables features.
Patrick.
∂22-Oct-87 1054 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: indefinite extent of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 10:54:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 260998; Thu 22-Oct-87 13:55:24 EDT
Date: Thu, 22 Oct 87 13:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: indefinite extent of call-next-method
To: kempf%hplabsz@hplabs.HP.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <7120.561915678@hplabsz>
Message-ID: <19871022175524.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
I said I didn't have an opinion on this issue and I wasn't going to
say anything, but having once opened my mouth, I can't let this kind
of reasoning go by.
Date: Thu, 22 Oct 87 08:41:18 PDT
From: kempf%hplabsz@hplabs.HP.COM
> I don't find Jim's argument convincing at all. To my mind,
> call-next-method is a function that is closed over the identity
> of the next method and the arguments to be passed to it, just
> as a function defined by labels with a free reference that is
> captured in an outer scope is closed over the variable in the
> free reference. In both cases it's equally true and equally
> irrelevant to the scope of the closure that the value of the
> closed-over variable is only known at run time.
The difference is that the name of the free reference in the case of a function
defined by LABELS or FLET is lexically apparent, while the identity
of the next method and arguments to be passed for CALL-NEXT-METHOD are not.
Come on! The lexical bindings of CALL-NEXT-METHOD and NEXT-METHOD-P are
put in automatically by the DEFMETHOD macro. Suppose they looked like this:
(flet ((next-method-p ()
(not (null clos-internal:next-method-function)))
(call-next-method (&rest arguments)
(unless clos-internal:next-method-function
(error "There is no next method"))
(apply clos-internal:next-method-function
(or arguments clos-internal:next-method-arguments))))
...body of method...)
Yes, the identity of the next method and arguments are not lexically
apparent, just as the values of the freely-referenced variables in a
flet are not lexically apparent. I think you're confusing the names
with the values. The -only- way I see that call-next-method is
different from other lexically local functions is that its definition is
put in by a macro, thus is not lexically apparent in the original source
code. The reason for that of course is so we don't have to document the
names and contracts of the particular variables it looks at to decide
what to do, leaving implementations some freedom.
The only thing I can think is that you people arguing for dynamic extent
instead of indefinite extent have in the back of your minds that the
variables I have called clos-internal:next-method-function and
clos-internal:next-method-arguments in the example above should be
special variables rather than lexical variables, and they get dynamically
bound by generic function dispatch. But we already determined
long ago that that can't work; I don't want to spend the time to dredge
up the mail reference, but consider this contrived example:
(defmethod gf1 ((x class-1) f)
(funcall f))
(defmethod gf2 ((x class-2))
(gf1 (slot-value x 'foo) #'call-next-method))
The point here is that even with dynamic extent, call-next-method
can be called inside a generic-function call that is different from
the one whose next method it refers to. We want the next method for
gf2, not the next method for gf1. This next example is even better
since only one generic function is involved:
(defmethod gf3 ((x t) n f)
n)
(defmethod gf3 ((x class-1) n f)
(if (zerop n)
(funcall f)
(gf3 x (1- n) #'(lambda ()
(* (funcall f)
(call-next-method))))))
(gf3 (make-instance 'class-1) 6 #'(lambda () 1))
should return 720, but would return 0 if special variables
were used to control call-next-method.
This means that a programmer trying to understand program structure for a
function defined by labels or FLET need only look at the source where the
function is passed out of scope, while, with CALL-NEXT-METHOD, the programmer
must run the code.
It's true that to know which particular method CALL-NEXT-METHOD is going
to call, one has to know what the applicable methods are, which can vary
at run time. Isn't that more or less the whole point of the existence
of CALL-NEXT-METHOD? To me, this doesn't seem to have any bearing on
what the extent of CALL-NEXT-METHOD should be. I guess you see it
differently.
In the case of the function, the values are dynamically
determined but the control structure is not, modulo function valued variables.
In the case of CALL-NEXT-METHOD, the control structure is dynamically
determined.
I can't reconcile these two sentences. Is the control structure in
CALL-NEXT-METHOD anything other than function valued variables?
Anticipating the question of "how does this differ from generic
functions or a direct call to CALL-NEXT-METHOD", in both these cases there
are lexical cues that control structure is dynamically calculated. In the
case of a generic function invocation, it is the name of the generic
function, for which the application of SYMBOL-FUNCTION will return a
generic function object. In the case of CALL-NEXT-METHOD, it is the lexical
context of a method definition. An executable entity enclosing a
CALL-NEXT-METHOD passed out of scope could be any one of a number of
things, some of which will give no clue that they enclose a CALL-NEXT-METHOD.
I don't disagree with that, but can't see how it's relevant.
I understand your and Pavel's concern, however, I have a couple of problems
with this. I think it is important that the implications of making
CALL-NEXT-METHOD indefinite in extent be outlined up front, rather than
having implementors duplicate the discussion we've been going through.
This has been the case for other new concepts we've introduced, such as
generic functions. The other problem is one of design philosophy, which
is, of course, open to debate. I believe that it is usually a good idea
to offer people an "economy" option and a "luxury" option. Although
it's always dangerous to say what "most" people do, I think most
programmers won't be affected if CALL-NEXT-METHOD is implemented either
way.
I agree that passing a closure of CALL-NEXT-METHOD upward will be quite rare.
This is why I don't care much about this issue. I see it as only an academic
issue of language cleanliness, rather than something that will make a big
difference to users; the latter issues are the ones I care more about. Of
course I'd rather see a simpler and cleaner language too, if we can agree.
On the other hand, I can imagine certain "economy" CL implementations
in which implementing CALL-NEXT-METHOD as having indefinite extend may
be difficult, or adversely impact use of CALL-NEXT-METHOD in some manner.
Thus Dick's solution of specifying dynamic extent (as the "economy" option)
with "indefinite" as an allowable extention (as the "luxury" option)
appeals to me.
I still can't see how the issues for CALL-NEXT-METHOD are different from
the issues for any lexically local function, yet CLtL does not offer
implementations the choice of only implementing "downward" funargs.
∂22-Oct-87 1108 Moon@STONY-BROOK.SCRC.Symbolics.COM Keene comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:08:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261017; Thu 22-Oct-87 14:09:25 EDT
Date: Thu, 22 Oct 87 14:09 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Keene comments on Chapter 1
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871022153612.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <19871022180926.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 22 Oct 87 11:36 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
In general, the spec seems to be coming together nicely. I think it
reads better than it used to, and the tone is quite consistent
throughout.
I agree with this, but forgot to say so in my earlier comments. I may
be "madly" reviewing the document, but so far I haven't found anything
to make me mad. Chapter 1 seems to be in excellent shape and there
should be no problems finishing it. I'm about to start reading Chapter 2.
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because it
is the default doesn't mean that it shouldn't have a name.
I strongly agree. The name should be just "standard" I think, rather
than the longer name, since the other m-c types have short names.
Method combination types aren't in the same namespace as anything else,
so they don't need to tack "-method-combination" onto the end of their
name to distinguish them.
1-31
We don't say here what happens if a generic function is called and
there is no applicable method at all. Presumably an error is signaled.
Should say that it calls no-applicable-method, and maybe mention that
the default method for that signals an error.
∂22-Oct-87 1129 Masinter.pa@Xerox.COM Re: indefinite extent of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 11:29:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 11:24:58 PDT
Date: 22 Oct 87 11:23 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: indefinite extent of call-next-method
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-112458-5149@Xerox>
For what its worth (which I hope isn't much), I've found the arguments
for indefinite convincing enough that I'm happy to change my vote from
"dynamic" to "indefinite".
My concern was that dynamic extent might not be implementable in some
situations, and I think I've seen how it is.
Part of my motivation for changing my vote is that I believe
categorically that "optional extensions" should be strongly discouraged
whenever possible, and, when present out of necessity, detectable by
well-known *features*, and their use lexically determinable.
∂22-Oct-87 1227 RPG Extent
To: common-lisp-object-system@SAIL.Stanford.EDU
Implementability is not the same as semantics. Methods are not functions.
(Methods include functions as parts. In fact, they can have generic
functions as parts.)
This debate is or ought to be about what methods are and what generic
functions are. Virtually all arguments I have seen that argue that
indefinite is correct also apply to TAGBODY's and GO's. If a method is
not a function, what is the etymology of ``CALL-NEXT-METHOD.''
Imagine a generic function with many methods - broken down into roughly
equal numbers of :around methods, :before methods, primary methods, and
:after methods. Suppose the generic function is invoked and after a couple
of primary methods are executed, a closure is thrown out that captures
CALL-NEXT-METHOD. Two years later someone stumbles across this closure and
FUNCALL's it. We're all happy to see the primary methods complete, and the
intended :after and :around methods ignored? (Of course, they didn't
complete the first time either, though the :before methods were executed.)
To me the execution of a generic function is a black box, just as TAGBODY
is. Because it is a black box, my understanding of the semantics of it
naturally includes the fact that CALL-NEXT-METHOD has ``hidden state.''
That is, to me an activation of a generic function includes imposing a
control structure on the methods and causing the functional objects
associated with methods to be invoked according to that control structure.
CALL-NEXT-METHOD is part of the control structure but not all of it. This
can be seen because the ``capturing of hidden state'' in my example does
not capture enough of the state to cause the generic function to complete.
If the method combination type were a linear CALL-NEXT-METHOD chain, the
effect would be the completion of the second part of the generic function.
Therefore, interrupting it strikes me as undesirable. Secondly, behavior
such as shown in my example strikes me as undesirable.
It is important for you to understand that my arguments about hidden state
follow from a decision about a principle - the black-box nature of the
execution of generic functions. They do not follow from imagining an
implementation and then reasoning about it. If you do not believe in the
black-box nature of the execution of generic functions, you will construct
arguments, semantics, and implementations that eliminate the hidden state.
If I were to accept the clear-box nature of generic function execution, I
would also explain the semantics with a nest of closures.
-rpg-
∂22-Oct-87 1303 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on chapter 2, through defgeneric
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:03:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261181; Thu 22-Oct-87 16:04:12 EDT
Date: Thu, 22 Oct 87 16:04 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on chapter 2, through defgeneric
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871022200408.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
2-6: This hasn't changed from 87-002, but I find the way the value of
add-method is described confusing. It isn't made perfectly clear
that the value is always eq to the first argument, rather than being
a copy of it with modifications. I'd prefer to write
"Values: {\it generic-function} is returned."
Compare the way it's done for change-class on 2-10, which is unambiguous,
but a little verbose.
================
2-7: The text that was in the previous version saying that the name
CALL-NEXT-METHOD only has a function definition within the lexical
scope of a method body got lost. We have to say something about this.
I think the most reasonable thing might be that outside the lexical
scope of a method body, CALL-NEXT-METHOD designates a function that
signals an error if called. We also have to say whether the lexical
scope of CALL-NEXT-METHOD includes forms in a method's lambda-list.
I prefer "yes", because in Flavors it used to be "no", and several
users complained so we had to change it. The implementation is
slightly more difficult, but only very slightly.
================
2-7 second Arguments paragraph: In one place this says an error is
signalled, in another it says the results are undefined, when bad
arguments are passed to call-next-method. Which is right? I don't
remember for sure but my notes from the the most recent meeting
indicate "signals an error." Also, the last sentence on this page
belongs in this paragraph, not in the paragraph that it is in.
================
2-11 last paragraph: This never says what the problem being compounded
is. It's that after changing the class of an argument, the methods
now executing or about to be executed might no longer be applicable.
================
2-20: the description of the slot options is a bit inconsistent about
whether it calls them "options" or "slot options". The introductory
phase for all but :initarg says just "option". I think I'd prefer
saying "slot option" everywhere when discussion slot options, although
that can get a bit verbose. In any case the style should be made consistent.
================
2-20 first bullet: "the setf generic function named generic-function-name"
should be "the generic function named (setf generic-function-name)".
================
2-20 last hyphenated bullet, last sentence: What it says here is slightly
oversimplified. If a class C1 defines a shared slot named S, a subclass
C2 can avoid sharing S without itself containing a slot specifier for S
in its defclass form, if C3 is a superclass of C2, C3 contains a slot
specifier for S, and C3 precedes C1 in the CPL of C2. There is probably
a clearer way to say what I just said.
================
2-21 second bullet: "The expression (typep value value-specifier) will
be true for the value stored in the slot" doesn't conform to the error
terminology introduced in chapter 1. I think we mean something like "If
the expression (typep value value-specifier) is not true for the value
stored in the slot, the results are undefined" but maybe this needs to
be phrased differently to clarify that what is undefined is for a program
to perform an action that would cause that expression to become untrue.
Also clarify that the type check does not apply to an uninitialized slot,
since such a slot does not have a value at all.
================
2-21: Just a reminder to everyone that the constructor writeup here is
not what anyone is proposing. It is neither exactly my proposal, nor
of course is it the null proposal. I presume we're letting it be until
we agree on what to do.
================
2-22 last bullet: remove this, with-slots no longer depends on the
class definition.
================
2-22 2/3 down the page: Change "No class options are inherited" to
"No class options except :default-initargs are inherited".
================
2-22 third paragraph from the bottom: "the initial value of the slot
is unspecified": this is incorrect. Change the phrase to "the slot
is uninitialized".
================
2-22 second paragraph from the bottom: :initarg can also appear more
than once in a slot description.
================
2-22 last paragraph: :default-initargs can also appear more than once in
a defclass.
================
2-24 fourth paragraph: The calls to fboundp and symbol-function are
missing quote marks. In the second sentence, new-value should be in
italics, not bold. Can this be rephrased to avoid introducing the term
"setf generic function"? Perhaps this paragraph could be merged into
the second paragraph, simply saying that -name- can be a symbol or
a setf-list. Then the fboundp/symbol-function rules wouldn't have to
be stated twice.
2-24 I'm not sure I understood the double square bracket notation used
in this chapter, but it appears to be saying that defgeneric is only
allowed one option. Maybe this is just a typo of a missing asterisk?
But maybe the syntax could be simplified by making -method-description-
a subcase of -option-. I'm not sure that -method-specifier- needs to
be a separate syntatic nonterminal symbol; why not merge this into
-method-description-?
2-24 I'd prefer not to have separate syntax for lambda-list and setf-lambda-list,
since this requires the reader to study them to figure out what is different.
It would be better to use one syntax and say in text that the new-value is
the first required argument (and therefore there must be at least one required
parameter). Affects 2-26 fifth paragraph, 2-28 fourth paragraph too.
2-24 I'm not sure we want to allow the (var) form for an optional parameter
specifier in defgeneric. The 87-002 document was ambiguous here, but I had
read it as allowing only a symbol as an optional parameter specifier, so I
was surprised to see that the other form was being allowed now too. Similarly
for keyword parameter specifiers, I would allow var and ((keyword var)), but
would forbid (var). The (var) forms seem to me likely to mislead someone
into thinking that default value forms are permitted here. I admit this is
a matter of taste.
2-25 last line: (eql -object-) should be (eql -form-) since -form- is
a form that gets evaluated at the time the defgeneric is evaluated, and
the value of -form- is the object that an argument has to be eql to to
satisfy the parameter specializer. Appears again on 2-27 fifth bullet.
2-26 discussion of optimize declaration: change "defmethod form" to
"defmethod form or method-description".
2-27 "specialized-setf-lambda-list" is mentioned here, but is not in the syntax.
It can be removed.
================
TYPOS:
2-20 last bullet: ":initform argument" should be ":initform slot option",
in two places.
2-22 first Remarks paragraph: remove the reference to change-class.
2-28 second Remarks paragraph: "a anonymous"
∂22-Oct-87 1306 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: indefinite extent of call-next-method
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:06:22 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 22 Oct 87 13:05:19-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Thu, 22 Oct 87 13:06:31 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 22 Oct 87 13:06:13 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 22 Oct 87 14:05:46 pdt
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.Stanford.EDU
Subject: Re: indefinite extent of call-next-method
X-Mailer: mh6.5
In-Reply-To: Your message of 22 Oct 87 12:27:00 -0700.
Date: Thu, 22 Oct 87 13:05:39 PDT
Message-Id: <10603.561931539@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> It is important for you to understand that my arguments about hidden state
> follow from a decision about a principle - the black-box nature of the
> execution of generic functions. They do not follow from imagining an
> implementation and then reasoning about it. If you do not believe in the
> black-box nature of the execution of generic functions, you will construct
> arguments, semantics, and implementations that eliminate the hidden state.
> If I were to accept the clear-box nature of generic function execution, I
> would also explain the semantics with a nest of closures.
This also explains what I was trying to get at, but Dick seems to have
expressed it more clearly. We seem to have a disagreement as to the fundamental
semantics. I'm willing to say "Tio" if you feel strongly about it, and
considering Masinter's comment about discouraging optional extensions, go
with indefinite.
jak
∂22-Oct-87 1318 Bobrow.pa@Xerox.COM Re: Extent
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 13:18:08 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 13:17:27 PDT
Date: 22 Oct 87 13:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Extent
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
12:27 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-131727-5334@Xerox>
To me the execution of a generic function is a black box, just
as TAGBODY is. Because it is a black box, my understanding of the
semantics of it naturally includes the fact that CALL-NEXT-METHOD
has ``hidden state.'' That is, to me an activation of a generic
function includes imposing a control structure on the methods and
causing the functional objects associated with methods to be
invoked according to that control structure. CALL-NEXT-METHOD is
part of the control structure but not all of it. This can be seen
because the ``capturing of hidden state'' in my example does not
capture enough of the state to cause the generic function to
complete. If the method combination type were a linear
CALL-NEXT-METHOD chain, the effect would be the completion of the
second part of the generic function.
To me the execution of a generic function is a clear box. Because the
user, through compute-effective-method, and its user interace
define-method-combination, is constructing the effective method from a
set of functions the he/she explicitly handles, the operation of this
clear box is well defined. I agree with Moon that the only reason not
to publicize the name is to allow implementtion freedom So this argues
for indefinite extent.
danny
∂22-Oct-87 1338 RPG Clear Versus Black Box
To: common-lisp-object-system@SAIL.Stanford.EDU
To the author of the generic function, the box is clear - but only during
that authorship. To the user it is black during execution. Therefore any
construct that opens a window into it is forbidden.
The actions of any FORTRAN program are well-defined. I believe we all
agree that FORTRAN was not well defined.
``I agree with Moon that the only reason not to publicize the name is to
allow implementtion freedom.''
If this would be the only reason, then the clarity of the box is
irrelevant.
-rpg-
∂22-Oct-87 1424 Pavel.pa@Xerox.COM Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:23:53 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 OCT 87 14:15:27 PDT
Date: Thu, 22 Oct 87 14:15:21 PDT
From: Pavel.pa@Xerox.COM
Subject: Comments on comments on Chapter 1
In-reply-to: <19871022033419.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-141527-5413@Xerox>
I agree strongly with Moon that the concept of "setf generic function"
is now essentially bankrupt and that we shouldn't give it any real
emphasis in the proposal.
Moon says:
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
I would rather that the word used here was "sequence" instead of "list",
just because "sequence" is a bit less evocative of a particular Lisp
data structure.
Moon says:
1-11 last sentence: needs to be updated with a correction I sent
earlier,
because :default-initargs can appear more than once in a defclass.
Perhaps I'm just missing something, but what's the use of multiple
:default-initargs options?
Moon says:
1-16 fourth paragraph last sentence: "It is not allowed" is not defined
in the error terminology section. I think you mean "CLOS may be
extended to cover make-instance of a standard-type class or inclusion
of
a standard type class as a superclass of a class."
I like this wording much better. The other wording, aside from being
undefined, implied to me that such extensions were not acceptable.
Simon says (oops, I mean Moon says):
1-23 last bullet: "(EQL -object-)" should be "(EQL -form-)", because
in a parameter specializer name, we have a form that is to be evaluated
to produce the object that appears in the parameter specializer. The
paragraph immediately following is wrong where it says "otherwise N
equals P" for this reason. We changed this when we changed QUOTE to
EQL.
So, to test my understanding, "(EQL -form-)" is a parameter specializer
name and "(EQL -object-)" is the resulting parameter specializer, where
-object- is the result of evaluating -form-. Is this right?
Moon says:
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
I agree with this. I was surprised when I saw that LIST was more
specific than SYMBOL.
Sonya says:
1-17, Figure 1-1
The column header "Superclasses" doesn't make it clear that the order
of
these classes is from most to least specific. In my draft of this
the
column header was "Class Precedence List", which did make this clear.
I would also prefer "Class Precedence List" to "Superclasses" here.
Sonya says:
1-21, 3rd paragraph
"Ordinary functions and generic functions are called with identical
syntax." I can't remember for sure, but I believe we decided that
generic functions must have at least one required argument. If so,
this is one (minor) syntactic difference between ordinary and generic
functions.
If this has, indeed, been decided, the document should say so somewhere.
Does it? I could imagine uses for generic functions without arguments.
For example, the only distinction could be in the qualifiers, which
could, perhaps, be integers implementing some sort of method priority
scheme. Was there a real reason for this decision, if indeed it has
been made?
Sonya and Moon say:
1-30, Standard Method Combination
I think the standard method combination should have a name, such as
"standard-method-combination". That name should be able to be given
to the :method-combination option to defgeneric, etc. It should be
noted as one of the Built-in Method Combination types. Just because
it
is the default doesn't mean that it shouldn't have a name.
I strongly agree. The name should be just "standard" I think, rather
than the longer name, since the other m-c types have short names.
Method combination types aren't in the same namespace as anything
else,
so they don't need to tack "-method-combination" onto the end of
their
name to distinguish them.
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types aren't
named with keywords is to make their association with the Lisp operators
clear.
Pavel
∂22-Oct-87 1446 Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:46:45 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261315; Thu 22-Oct-87 17:47:10 EDT
Date: Thu, 22 Oct 87 17:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on comments on Chapter 1
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-141527-5413@Xerox>
Message-ID: <19871022214711.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 22 Oct 87 14:15:21 PDT
From: Pavel.pa@Xerox.COM
1-3 sixth paragraph: "ordered set" should be "list" in two places,
to avoid implying that duplicates are eliminated from the "set" of
parameter specializers or the "set" of qualifiers.
1-23 first paragraph under Introduction to Methods: same comment.
I would rather that the word used here was "sequence" instead of "list",
just because "sequence" is a bit less evocative of a particular Lisp
data structure.
Good idea. I like "ordered sequence" here.
Perhaps I'm just missing something, but what's the use of multiple
:default-initargs options?
defclass' philosophy appears to be to allow all options and slot options
to appear multiple times unless repetition has to be forbidden because
it would be meaningless. I think multiple :default-initargs options
just act like they were concatenated.
So, to test my understanding, "(EQL -form-)" is a parameter specializer
name and "(EQL -object-)" is the resulting parameter specializer, where
-object- is the result of evaluating -form-. Is this right?
Right. At Dick's request I mailed him a rewrite of this portion of this
section that I think should clarify everything better than my comment.
Moon says: ....
I agree with this. I was surprised when I saw that LIST was more
specific than SYMBOL.
Thank you.
[name of] Standard Method Combination
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types aren't
named with keywords is to make their association with the Lisp operators
clear.
I don't understand what you mean by "intrinsic meaning". Binding to
a method-combination type is as intrinsic as binding to a value in my book.
However, I have no objection to using a keyword as the name, other than
that we'll have to change the second sentence under Arguments on page 2-29
slightly.
∂22-Oct-87 1458 Pavel.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 14:58:38 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 OCT 87 14:56:09 PDT
Date: Thu, 22 Oct 87 14:56:04 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Comments on comments on Chapter 1
In-reply-to: <19871022214711.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871022-145609-5495@Xerox>
I said, in reference to the name for standard method combination:
Rather than add one more symbol in the LISP package that has no
intrinsic meaning (e.g., no value), I would like to see this named
:STANDARD. The only reason the various other built-in m-c types
aren't
named with keywords is to make their association with the Lisp
operators
clear.
Moon replied:
I don't understand what you mean by "intrinsic meaning". Binding to
a method-combination type is as intrinsic as binding to a value in my
book.
However, I have no objection to using a keyword as the name, other
than
that we'll have to change the second sentence under Arguments on page
2-29
slightly.
I think that there's no qualitative difference between the argument
:OVERWRITE to the :IF-EXISTS parameter of OPEN and the argument VARIABLE
to the second parameter of DOCUMENTATION. Yet, in Common Lisp, one of
these is required to be a keyword and the other is required to be in the
LISP package. I think that there are a lot of these kinds of symbols
that should all have been keywords.
Pavel
∂22-Oct-87 1521 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:21:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:17:19 PDT
Date: 22 Oct 87 15:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Clear Versus Black Box
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
13:38 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-151719-5532@Xerox>
To the author of the generic function, the box is clear - but
only during that authorship. To the user it is black during
execution. Therefore any construct that opens a window into it is
forbidden.
To the author of any function, its actions are clear. To the user using
it, it is opaque. I see no difference between the opacity of using a
closure over an flet function, and one using call-next-method. Both
insides are apparent to the function writer; both are opaque to the
closure user. It is how the program writer views a method that I am
concerned with. It is that person who is exporting something that has
indefinite extent.
danny
∂22-Oct-87 1536 Bobrow.pa@Xerox.COM Re: Clear Versus Black Box
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:21:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:17:19 PDT
Date: 22 Oct 87 15:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Clear Versus Black Box
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
13:38 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-151719-5532@Xerox>
To the author of the generic function, the box is clear - but
only during that authorship. To the user it is black during
execution. Therefore any construct that opens a window into it is
forbidden.
To the author of any function, its actions are clear. To the user using
it, it is opaque. I see no difference between the opacity of using a
closure over an flet function, and one using call-next-method. Both
insides are apparent to the function writer; both are opaque to the
closure user. It is how the program writer views a method that I am
concerned with. It is that person who is exporting something that has
indefinite extent.
danny
∂22-Oct-87 1544 Moon@STONY-BROOK.SCRC.Symbolics.COM Second set of comments on chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 15:44:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 261398; Thu 22-Oct-87 18:38:03 EDT
Date: Thu, 22 Oct 87 18:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Second set of comments on chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871022223800.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
These comments cover defgeneric (slightly revised from what I mailed
out earlier) through remove-method.
2-24 fourth paragraph: The calls to fboundp and symbol-function are
missing quote marks. In the second sentence, new-value should be in
italics, not bold. Can this be rephrased to avoid introducing the term
"setf generic function"? Perhaps this paragraph could be merged into
the second paragraph, simply saying that -name- can be a symbol or
a setf-list. Then the fboundp/symbol-function rules wouldn't have to
be stated twice.
2-24 I'm not sure I understood the double square bracket notation used
in this chapter, but it appears to be saying that defgeneric is only
allowed one option. Maybe this is just a typo of a missing asterisk?
But maybe the syntax could be simplified by making -method-description-
a subcase of -option-. I'm not sure that -method-specifier- needs to
be a separate syntatic nonterminal symbol; why not merge this into
-method-description-?
2-44, 2-46, 2-48, 2-77: ditto
2-24 I'd prefer not to have separate syntax for lambda-list and setf-lambda-list,
since this requires the reader to study them to figure out what is different.
It would be better to use one syntax and say in text that the new-value is
the first required argument (and therefore there must be at least one required
parameter). Affects 2-26 fifth paragraph, 2-28 fourth paragraph too.
2-44, 2-48, 2-77: ditto
2-24 I'm not sure we want to allow the (var) form for an optional parameter
specifier in defgeneric. The 87-002 document was ambiguous here, but I had
read it as allowing only a symbol as an optional parameter specifier, so I
was surprised to see that the other form was being allowed now too. Similarly
for keyword parameter specifiers, I would allow var and ((keyword var)), but
would forbid (var). The (var) forms seem to me likely to mislead someone
into thinking that default value forms are permitted here. I admit this is
a matter of taste.
2-44, 2-48, 2-77: ditto
2-25 last line: (eql -object-) should be (eql -form-) since -form- is
a form that gets evaluated at the time the defgeneric is evaluated, and
the value of -form- is the object that an argument has to be eql to to
satisfy the parameter specializer. Appears again on 2-27 fifth bullet.
2-26 discussion of optimize declaration: change "defmethod form" to
"defmethod form or method-description".
2-27 "specialized-setf-lambda-list" is mentioned here, but is not in the syntax.
It can be removed.
================
2-30 end of third bullet: "but this is not required" should perhaps be
"this is the default, but is not required", since -operator- defaults to -name-.
2-30 third paragraph from bottom of page last sentence: "define by the
define-method-combination macro", insert "the short form of".
================
2-36 last Purpose paragraph: I don't think we need the concept of "setf
generic function", so I'd like to see this paragraph go away.
2-37 second paragraph: ditto.
2-36 last line: (eql -object-) should be (eql -form-). Also maybe
-symbol- should be -class-name- for increased clarity.
2-37 fourth paragraph: ditto. Here we need to explain about -object-
being the value of -form-, as on 1-23.
================
2-40 Add missing bullets: "The form (documentation -symbol- 'variable)
returns the documentation string of the special variable or constant
named by the symbol. The form (documentation -symbol- 'structure)
returns the documentation string of the {\bf defstruct} structure named
by the symbol."
================
2-42 second Purpose paragraph: This is wrong, isn't it? Shouldn't it
say the same thing as defgeneric says, namely if (fboundp -name-) is
nil, a new generic function is created and stored there, otherwise
if (symbol-function -name-) is not a generic function, signal an error.
================
2-42 first Arguments paragraph second sentence: I think we can delete
this sentence, the concept of setf generic functions isn't useful.
================
2-54 syntax: delete the italicized word "initargs". The make-instance
generic function doesn't have any keyword parameters of its own. In
the second arguments paragraph, change "The -initargs- argument is" to
"The remaining arguments are".
================
2-54 first remarks paragraph: I think this is misleading. Instantiating
a standard type class has to be "may be extended" rather than "signals
an error", since in a given implementation a standard type class can
be implemented as a standard class. The paragraph as written is not
actually wrong, because it carefully refers to what the metaclass actually
is rather than whether the class is documented as a standard type class.
However, I think there is plenty of scope for confusion here and the
wording should be clarified somehow.
================
2-56: I don't like the use of -old-class- as the name of the argument to
make-instances-obsolete. There isn't anything old about the class object,
it remains in effect. I'd rather it was just named -class-.
================
2-57 add to Arguments section: If -method-list- is nil and :operator is
:call-next-method, the result is nil.
2-57 last paragraph: Delete.
================
2-60: I think method-qualifiers belongs in chapter 3. I know it's
referenced on page 2-32, I still think it belongs in chapter 3.
================
OPEN ISSUES:
2-37 second Remarks paragraph: We need to decide whether defmethod
creates a new method object or modifies the existing one, and say
explicitly which it is. I prefer modifying the existing one, and
the way add-method is described suggests to me that this is what is
intended, but I think Gregor disagrees.
2-55: I suspect more initargs are needed when creating an instance
of standard-method. Certainly something has to be done to make the
method's keyword parameter keyword names available, because of the
way keyword arguments to generic functions now work. Do the metafolks
have a suggestion here?
================
TYPOS:
2-28 second Remarks paragraph: "a anonymous"
2-34 line 6: "(progn" should be indented. The two make-method-call
forms that are inside the progn should be indented another space or
two to make the nesting structure more obvious.
2-23 In the first "define-method-combination and", delete "()" from
the methods clause, so unqualified methods will not be accepted.
2-42 third Purpose paragraph: "that has different value", add "a".
2-42 fourth Purpose paragraph: "and there are no methods" should
be "or there are no methods".
2-61 purpose: "next-method-s" should be "next-method-p".
================
∂22-Oct-87 1554 RPG 0-ary generic functions
To: common-lisp-object-system@SAIL.Stanford.EDU
I believe this idea tickled us when we were discussing delegation
in Palo Alto. The idea was to have every generic function have at least
one required parameter so that no-applicable-method would have something
to discriminate on. After I heard this the next thing I remembered was a
guy in a green coat waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
-rpg-
∂22-Oct-87 1606 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM 0-ary generic functions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:06:30 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 261452; 22 Oct 87 19:07:31 EDT
Date: Thu, 22 Oct 87 19:07 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: 0-ary generic functions
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 22 Oct 87 18:54 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871022230724.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 1554 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I believe this idea tickled us when we were discussing delegation
in Palo Alto. The idea was to have every generic function have at least
one required parameter so that no-applicable-method would have something
to discriminate on. After I heard this the next thing I remembered was a
guy in a green coat waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
I think Dick is right: We flirted with, but in the end did not adopt,
a restriction that a generic function must have at least one required
parameter.
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:21 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 15:32:24 PDT
Date: 22 Oct 87 15:32 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on comments on Chapter 1
In-reply-to: Pavel.pa's message of Thu, 22 Oct 87 14:15:21 PDT
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-153224-5558@Xerox>
Moon says:
1-17 I still think it's wrong for list to be more specific than symbol
in the CPL of null. Consider the print-object methods. Also consider
the introjection of symbol between list and sequence, a surprising CPL.
Pavel says
I agree with this. I was surprised when I saw that LIST was
more specific than SYMBOL.
The motivating example for this was something like:
(defmethod some-mapper ((x listp) fn)
(when x (funcall fn (car x)) (some-mapper (cdr x) fn))
(defmethod some-mapper ((x symbolp) fn)
(some-mapper (look-up-in-table x *table*) fn)
Here one wants the recursion to NIL to be handled in the listp case
without having to think about the method on symbolp. What is an example
in which one would want this another way. I think we should in this
case be driven by some examples, since this pun in Lisp is
atheoretic.(NIL is the same as empty list)
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: Comments on comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:21:14 PDT
Date: 22 Oct 87 16:21 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comments on comments on Chapter 1
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-162114-5666@Xerox>
Moon:
1-17 I still think it's wrong for list to be more specific than
symbol in the CPL of null. Consider the print-object methods.
Also consider the introjection of symbol between list and sequence,
a surprising CPL.
I understand the first point. This comes to the point of whether one
wants to print NIL
as ()
or NIL
I don't understand the second point. What do you mean by introjection
here? Show the surprise please (not that I wasn't surprised --- I just
couldn't open the box).
danny
∂22-Oct-87 1622 Bobrow.pa@Xerox.COM Re: First round of comments on the draft document
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:22:31 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:07:36 PDT
Date: 22 Oct 87 16:07 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: First round of comments on the draft document
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871022-160736-5631@Xerox>
================
1-16 fourth paragraph last sentence: "It is not allowed" is not
defined in the error terminology section. I think you mean "CLOS
may be extended to cover make-instance of a standard-type class or
inclusion of a standard type class as a superclass of a class."
I think the concept of standard-type-class was one we had eliminated. I
think a potentially better way to describe these this mapping is:
"The classes corresponding to predefined Common Lisp data types can be
one of two types. There are those that are implemented specially in the
implementation, and these have metaclass built-in-class. For these
built-in classes, an error is signalled if a user tries to create an
instance of such a class using make-instance. An example of such a
class is integer. Some classes corresponding to predefined Common Lisp
data types may be implemented as instances of the standard metaclass.
For example, ratio or rational might be such classes (or stream if that
gets included). For these, instances can be made using make-instance.
It is implementation dependent which of the Common Lisp data type
classes are implemented in each way."
I suggest that where ever the expression "standard type class" is now
used, we use either built-in-class if we are referring to implementation
issues, and "Common Lisp data type classes" when we are referring to the
mapping.
Question: Will we allow specialization of built-in-classes. An example
of the use of this is having a general Newton-Rafson iteration method on
number, and allowing a new specialization of number that could inherit
such a method.
∂22-Oct-87 1631 Bobrow.pa@Xerox.COM Re: 0-ary generic functions
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 16:31:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 16:29:22 PDT
Date: 22 Oct 87 16:29 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: 0-ary generic functions
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 22 Oct 87
15:54 PDT
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871022-162922-5707@Xerox>
I believe this idea tickled us when we were discussing
delegation in Palo Alto. The idea was to have every generic
function have at least one required parameter so that
no-applicable-method would have something to discriminate on. After
I heard this the next thing I remembered was a guy in a green coat
waving a small bottle of ammonia under my nose.
I think we flushed this requirement. Anyone else remember it?
As the guy in the green coat, I remember flushing it. It went the way
of making the second arg to no-applicable-method be the first arg of the
original call to the generic function. So to keep Dick awake becasue he
and Linda are doing such a marvelous editing job, consider this glitch
as flushed.
danny
∂22-Oct-87 1840 Moon@YUKON.SCRC.Symbolics.COM comments on some standard type classes
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 18:40:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 281061; Thu 22-Oct-87 21:37:18 EDT
Date: Thu, 22 Oct 87 21:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on some standard type classes
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-162114-5666@Xerox>,
<871022-153224-5558@Xerox>
Message-ID: <19871023013700.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 16:21 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Moon:
1-17 I still think it's wrong for list to be more specific than
symbol in the CPL of null. Consider the print-object methods.
Also consider the introjection of symbol between list and sequence,
a surprising CPL.
I understand the first point. This comes to the point of whether one
wants to print NIL
as ()
or NIL
I don't understand the second point. What do you mean by introjection
here? Show the surprise please (not that I wasn't surprised --- I just
couldn't open the box).
The natural direct superclasses of null are list and symbol, in some
order. The CPL of list is (list sequence t), of symbol is (symbol t).
What surprised me was to see the CPL of null be (null list symbol
sequence t), which has symbol inserted in the middle of list's CPL.
Usually one expects to see non-intersecting superclass trees kept
disjoint in the CPL, thus I would have expected to see (null symbol list
sequence t) or at worst (null list sequence symbol t). The only way to
get (null list symbol sequence t) from the standard CPL algorithm is if
sequence is a direct superclass of null.
Date: 22 Oct 87 15:32 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The motivating example for this was something like:
(defmethod some-mapper ((x listp) fn)
(when x (funcall fn (car x)) (some-mapper (cdr x) fn))
(defmethod some-mapper ((x symbolp) fn)
(some-mapper (look-up-in-table x *table*) fn)
Here one wants the recursion to NIL to be handled in the listp case
without having to think about the method on symbolp.
I guess. It's actually a bit strange that the list method thinks it's
really important to be called for both empty and non-empty lists, but
the first thing it does is to split into two disjoint code sequences,
one for empty lists and the other for non-empty lists. It makes me
wonder why you didn't write
(defmethod some-mapper ((x list) fn)
(funcall fn (car x))
(some-mapper (cdr x) fn))
(defmethod some-mapper ((x null) fn)
(declare (ignore fn))
nil)
I think what you are really objecting to is that there is no class name
for the subclass of SYMBOL that includes all symbols other than NIL.
The Common Lisp type system doesn't need a name for that, because you
can say (and symbol (not null)), but CLOS doesn't allow that as a
parameter specializer name.
Of course if your first method had been
(defmethod some-mapper ((x sequence) fn)
(map nil fn x))
it would not have worked, with the CPL as currently in the document.
That's another way of making my "introjection" point.
What is an example in which one would want this another way.
Well, there's the one I already mentioned:
;; Simplified to ignore *print-escape*, *print-case*
(defmethod print-object ((x symbol) stream)
(maybe-print-package-prefix x stream)
(write-string (symbol-name symbol) stream))
;; Simplified to ignore *print-length*, *print-pretty*
(defmethod print-object ((x list) stream)
(do ((c #\( #\space))
((atom x))
(write-char c stream)
(print-object (pop x) stream))
(when x
(write-string " . " stream)
(print-object x stream))
(write-char #\) stream))
Here we want the symbol method when x is NIL.
Now of course you're going to tell me that CLOS does have a class name
for the subclass of LIST that includes all lists other than (), and
therefore it's easier to fix my example to conform to your CPL than it
is to fix your example to conform to my CPL. While that's true, it
seems like backwards reasoning somehow.
I guess I can accept (null list sequence symbol t) as the CPL, although
I still think (null symbol list sequence t) fits the rest of the language
a little better. Maybe that's because all the built-in symbol functions
work for nil, but only some of the built-in list functions work for nil.
Maybe I'm just confused in thinking that rplaca is a list function rather
than a cons function. Or, in other words, you should almost never put
a method on LIST, because that class is too general; put it on CONS instead.
I think we should in this
case be driven by some examples, since this pun in Lisp is
atheoretic.(NIL is the same as empty list)
Agreed, in Common Lisp NIL is always a headache one way or another.
I'm sure we can find any number of examples in support of each of the
possible CPLs, so examples may not help much to reach a decision.
Oh by the way, while I have your attention, what about the other potential
standard-type classes: function, hash-table, package, pathname,
random-state, readtable, and stream. I think these are awaiting
cleanup action to straighten out the subtype and disjointness relations
of these in the CL type system before CLOS adopts them; should these
names be listed in our document? The CL-Cleanup issue FUNCTION-TYPE
should take care of the first of these; the rest depend on
PATHNAME-HASH-TABLE-TYPE-DISTINCT, which seems to have dropped through
the cracks, unless that's just the extreme imperfection of my personal
records.
From June 10:
4. ISSUE: PATHNAME-HASH-TABLE-TYPE-DISTINCT
Mandating a bunch of types (I don't have the complete list right now)
to be disjoint from a bunch of other types (again I don't have a
complete list right now) so that they can all be made into classes
without establishing any implementation-dependent subclass relationships.
[the types STREAM, PACKAGE, PATHNAME, READTABLE and RANDOM-STATE can be
required to be disjoint from other types (e.g., as if they had been created
with DEFSTRUCT.)
I don't think we currently require structures to be a disjoint
type from vectors, etc., though this has been talked about. So that
should be part of any proposal. --Fahlman ]
∂22-Oct-87 1907 Moon@YUKON.SCRC.Symbolics.COM standard-type-class or built-in-class
Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 19:07:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 281063; Thu 22-Oct-87 22:08:25 EDT
Date: Thu, 22 Oct 87 22:08 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: standard-type-class or built-in-class
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-160736-5631@Xerox>
Message-ID: <19871023020806.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 22 Oct 87 16:07 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
I think the concept of standard-type-class was one we had eliminated. I
think a potentially better way to describe these this mapping is:
"The classes corresponding to predefined Common Lisp data types can be
one of two types. There are those that are implemented specially in the
implementation, and these have metaclass built-in-class. For these
built-in classes, an error is signalled if a user tries to create an
instance of such a class using make-instance. An example of such a
class is integer.
Add "in almost all implementations"; we can never guarantee that any class
is built-in in all implementations.
Some classes corresponding to predefined Common Lisp
data types may be implemented as instances of the standard metaclass.
For example, ratio or rational might be such classes (or stream if that
gets included). For these, instances can be made using make-instance.
It is implementation dependent which of the Common Lisp data type
classes are implemented in each way."
I suggest that where ever the expression "standard type class" is now
used, we use either built-in-class if we are referring to implementation
issues, and "Common Lisp data type classes" when we are referring to the
mapping.
I remember we discussed this, but I don't have any record of a decision
having been made. I like your suggestion here and favor adopting it,
even at this late date. I think the key thing you are suggesting is that
the CLOS standard admits that the meta-class of some objects is
implementation-dependent, but having granted that, is free to be more
specific about how the meta-class controls the behavior.
We'd want to add "No portable program can depend on whether a Common Lisp
data type class is a built-in-class or a standard-class" (this phrase
is essentially lifted from the Error Terminology section).
Question: Will we allow specialization of built-in-classes. An example
of the use of this is having a general Newton-Rafson iteration method on
number, and allowing a new specialization of number that could inherit
such a method.
If a subclass of a built-in-class is a built-in-class, we cannot allow it,
since by definition only the implementor can create new built-in-classes.
Perhaps you're asking whether a standard-class can be a subclass of a
built-in-class; this is asking for trouble, because some methods on
the built-in-class are likely to depend on instances' implementation-specific
structure, and although they would be applicable to the subclass, they
would not work. I think we want to carry the current prohibition on
subclassing of standard-type-classes over to built-in-classes.
You could also be asking whether we should say that number is so general
a class that it would never be built-in to an implementation, so we will
say that number is a standard-class, even though some of its subclasses
may be built-in-classes. This bothers me too, because CLtL contains
"generic" functions such as + that are defined to work on all subtypes
of number, and if we allow adding new subtypes of number, then we have
to add a way to define methods for +, which is something that we made
an explicit non-goal back at the beginning of this effort.
∂22-Oct-87 1947 Pavel.pa@Xerox.COM My comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Oct 87 19:46:58 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 OCT 87 19:42:53 PDT
Date: Thu, 22 Oct 87 19:42:37 PDT
From: Pavel.pa@Xerox.COM
Subject: My comments on Chapter 1
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <871022-194253-5965@Xerox>
Here are those of my comments that haven't already been covered by Moon
and Sonya. Some of these are typos and some are more substantial, but I
haven't got the energy at this point to go through and separate them
out.
Pavel
Page 1-4, second paragraph, last sentence -- A typo: "the syntax of
Object System" should be "the syntax of the Object System".
Page 1-4, second set of bullets, second bullet -- Can't valid programs
rely on that error being signalled if they also specify (SAFETY 3)? I'm
generally unhappy with the phrase "at least in code compiled under one
compiler safety optimization level". I'd prefer a direct statement that
that level is 3.
Page 1-5, third bullet -- What does the clause "but they must remain
undefined" mean? Does that mean that my implementation is incorrect if
I document just which nasty bug will crop up if situation S occurs? I
can't derive any useful content from this clause.
Page 1-6, third and fourth paragraphs -- On my copy, produced by TeXing
the source with the AMFONT file in use, the not-equal symbol comes out
funny; in particular, it does not use the proper slash to cross out the
equals sign. I traced to problem to the AMFONT file. In the last six
or so lines of this, several uses of CM fonts were not changed into
their AM equivalents. Thus, our ancient Dovers used the old, OLD CM
fonts, which have a different layout of characters.
Page 1-6, eighth paragraph -- Should "class named t" be "class with the
proper name t"? I have a lot of reservations and questions about the
class-naming solution presented here, but I think I'll send them out
separately.
Page 1-7, first bullet -- Should this be "A proper name for the new
class"?
Page 1-7, sixth bullet -- I agree with Sonya (I think) that this should
say "methods for certain generic functions" rather than use the term
"appropriately named".
Page 1-8, third paragraph, first line -- "a slot which is visible"
should be "a slot that is visible"
Page 1-11, second bullet, last sentence -- "contains :type slot option"
should be "contains the :type slot option
Page 1-11, last paragraph in the section that ends here -- I found this
to be a very surprising statement until I remembered that everything
having to do with slots is defined ultimately in terms of SLOT-VALUE.
Some of my surprise could have been avoided by a mention of SLOT-VALUE
as the reason for this mildly unintuitive notion.
Page 1-13, second paragraph, fifth line -- Is there any reason this
mentions the EQ function instead of the more usual EQL function?
Page 1-13, second paragraph, last line -- a hyphen is missing in
"implementation dependent". Such a hyphen is not required except to be
consistent with other uses of "implementation-dependent", as in earlier
lines of the same paragraph.
Page 1-13, third paragraph -- Is there any way for a user to know if a
particular redefinition of a class will change "the order of slots in
storage"? I found this criterion very much out of place. Is it there
for a reason? If so, isn't it possible that there are other
implementation-dependent reasons that a class redefinition would
necessitate updating instances?
Page 1-15 -- I would like to add my voice to Moon's and Sonya's for
changing the name of this section to "Changing the Class of an
Instance".
Page 1-15, fifth paragraph -- I certainly hope that Moon is right and
that this paragraph should simply be deleted.
Page 1-16, second paragraph -- The phrase "the proper name" ignores the
possibility that, by the definition given on page 1-6, a given class can
have many proper names. Also in this paragraph, the phrase "some class
C named S" appears. I'm not sure what's meant here. Is this saying
that S = (CLASS-NAME C)? If so, it should say so more clearly. I think
that I must be missing something that supposed to have been said back on
page 1-6...
Page 1-17, table -- The contents of the table, not the headings, should
be in a fixed-pitch font.
Page 1-17, first line -- This says "Note that instances of standard
classes are type disjoint with all other types." I can't make any sense
of this.
Page 1-17 -- What is the cleanup status of the other types that we
wanted to give classes to, such as STREAM, PATHNAME, etc.?
Page 1-19, first paragraph -- The implicit "proof" here concerning the
uniqueness of a rightmost direct subclass might want ot be spelled out a
bit more. Also, in the last line, it isn't clear to me how there can be
no such candidate classes. Does someone have an example?
Page 1-19, second paragraph -- Is there a reason to use the unusual
forms "2 <= m" and "1 <= n" instead of the more common "m >= 2" and "n
>= 1"?
Page 1-19, the example -- A good example, but it would be better with
some sort of picture. Perhaps one can be pasted in or even done with
(gack!) character graphics. If the document we done in LaTeX, I'd
recommend using its "picture" environment, but it isn't...
Page 1-23, second paragraph in the new section -- In the last sentence,
the phrase "the new definition" should probably be replaced by "the
method-function object".
Page 1-23, third paragraph in the new section, second sentence -- For
clarity the word "required" should be added before the last word in the
sentence.
Page 1-23, second-to-last paragraph -- I think that the clause "if N is
a class name, then P is the class with that name" should be "if N is a
symbol and (CBOUNDP N) is true, then P is (SYMBOL-CLASS N)".
Page 1-23, last sentence -- Since GET-METHOD does not create a method,
the phrase "functional interface to method creation" should perhaps be
""functional interface to method manipulation".
Page 1-24, fourth paragraph -- I think this would be clearer written as
"This proposal specifies that all parameter specializers and parameter
specializer names are Common Lisp type specifiers."
Page 1-24, eighth paragraph -- The reason why qualifiers can't be lists
(ambiguity in the syntax of DEFMETHOD) should be mentioned. Otherwise,
this just sticks out as a weird glitch.
Page 1-25 -- I'm now confused about what the generic function's
lambda-list is used for. It appears to affect only the checking for
congruency. Is that really all it's for? If so, this seems a bit odd.
Page 1-27, third bullet -- This would be clearer, I think, as "For each
method, which other method, if any, is called when CALL-NEXT-METHOD is
invoked".
Page 1-28, fourth complete paragraph, last line -- If the method called
by invoking CALL-NEXT-METHOD is to be called the "next method" in
general, without regard to the method-combination type, then this line
should be in a different paragraph, one that doesn't so strongly tie
itself to standard method-combination.
Page 1-29, first and second bullets -- The words "primary method" at the
end of each of these should perhaps be "primary method(s)" instead,
since there can be more than one primary method.
Page 1-29, first and third ticks of the sixth bullet --
"most-specific-first" and "most-specific-last" really need the hyphens.
Page 1-29 -- I really don't like the name NEXT-METHOD-P. It sounds like
I pass it a method object and it tells me whether or not that method is
"next". Perhaps NEXT-METHOD-EXISTS-P?
Page 1-33, second bullet -- The "it is not allowed" phrase mentioned by
others pops up here as well and should be changed.
Page 1-33, third section -- The term "meta-objects" has not been defined
anywhere.
Page 1-35, third complete paragraph -- "initform" is not a word, so this
should perhaps be ":initform option".
Page 1-36, second complete paragraph -- Since an initialization argument
can be declared as valid by a method on initialize-instance, it is a bit
weird to speak of "the class that declared the initialization argument
as valid".
Page 1-38, table -- It would be nice if this were formatted as nicely as
the table on page 1-17.
Page 1-38, first sentence -- There should be a general line somewhere
stating that all generic functions defined by the proposal (unless
explicitly mentioned otherwise? Are there any exceptions?) use standard
method combination.
∂22-Oct-87 2004 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on final portion of Chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Oct 87 20:04:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 261601; 22 Oct 87 22:42:47 EDT
Date: Thu, 22 Oct 87 22:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on final portion of Chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871023024247.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
These comments apply to slot-boundp through with-slots. I'll try
to comment on chapter 3 tomorrow.
2-66 first sentence: this uses the term "bound" where elsewhere in the
document we use "not uninitialized". Admittedly there is some incoherence
between the function names and the document terminology, but I think the
document should be self-consistent and specifically relate to the term
"uninitialized" here.
2-66: Add a remark that if no slot by that name exists, we do
(SLOT-MISSING (CLASS-OF instance) instance slot-name 'SLOT-BOUNDP).
2-68: ditto
2-71: ditto (cover setf case too). Also cross-reference slot-unbound.
================
2-69 slot-missing should say under Values what gets done with
the values, if you write a method that returns some instead of
signalling an error. They get returned as the values of the original
function invocation.
2-70 ditto for slot-unbound: the value is returned in place of
the slot's value.
================
2-72: symbol-class of a symbol that is not cboundp should signal
an error, not return nil.
================
2-73: Clarify how -expansion- is used. Each reference to -symbol-
as a variable, that would be in the scope of a binding of -symbol-
as a variable at the point of the SYMBOL-MACROLET, is replaced
by -expansion- (-not- the result of evaluating -expansion-).
================
2-73: symbol-macrolet is a special form rather than a macro,
if it really works the way the last Remarks paragraph says. On
the other hand, if it works by making substitutions in its body
and returning the modified body, then it's a macro. The latter
implementation is easier for implementors of course, since they
don't have to change their interpreter, compiler, and tools to
understand a new special form and new kind of macro.
================
2-74 last Purpose sentence: update-instance-structure is not called
by change-class. It's called by something that doesn't have a documented
name inside the mechanism activated by make-instances-obsolete.
================
2-74, -75: rho and theta have been interchanged in the
update-instance-structure, (setf position-x), and
(setf position-y) methods, but are correct in the position-x
and position-y methods. Theta is the one to be set to atan.
So much for the perspicuity of greek letters.
================
2-78 first sentence: "setf generic function" again.
================
2-78 second bullet: calling change-class can't be right, this creates
a new generic function, it doesn't mung an existing one.
================
2-80 first Arguments paragraph: Are we sure we want to signal an error
for with-slots of a standard-type class? Why not use the normal
slot-missing mechanism? Of course we can't actually signal an error
here, because some standard-type classes can be implemented as standard
classes. But if this was changed to speak of built-in-class, it could
signal an error, but I still think it should go through slot-missing.
2-80 third arguments paragraph: ditto.
2-80 second Arguments paragraph: delete this paragraph.
2-81 third Remarks paragraph: ditto.
================
OPEN ISSUES:
2-78: what does with-added-methods do if -name- has a function definition
already, but the function isn't generic? Does it ignore it, signal an
error, or copy it into a default method? Signalling an error seems
safest.
================
TYPOS:
2-69 first Remarks paragraph: remove two spurious right parentheses.
2-73 first Remarks paragraph: "into calls to generic function", add "s".
2-75 first bullet: "each local slot in current class definition",
add "the".
2-78 paragraph 2: that's "defgeneric", not "def-generic".
2-78 first bullet: "has different value", add "a".
2-80 last Arguments paragraph: "the use of symbol", add "a".
================
∂22-Oct-87 2252 RPG Pavel's Comments
To: common-lisp-object-system@SAIL.Stanford.EDU
``Page 1-4, second set of bullets, second bullet -- Can't valid programs
rely on that error being signalled if they also specify (SAFETY 3)? I'm
generally unhappy with the phrase "at least in code compiled under one
compiler safety optimization level". I'd prefer a direct statement that
that level is 3.''
I don't to make CLOS depend on things that might change in Common Lisp
if I don't have to. Why state ``3'' when ``at least one'' will do?
``Page 1-5, third bullet -- What does the clause "but they must remain
undefined" mean? Does that mean that my implementation is incorrect if
I document just which nasty bug will crop up if situation S occurs? I
can't derive any useful content from this clause.''
As I mentioned in my message of July 8 containing the original proposal
which was accepted, this is to prevent implementations from using
the ``is an error'' out from Common Lisp. In Common Lisp, ``it is an
error'' means that no valid Common Lisp program should cause this situation
to occur and that the results are ``completely undefined.'' Steele goes on
to say that ``some particular implementation might ... define the effects and
results for such a situation.'' Steele mentions that ``must not'' means
``is an error.''
I have heard people argue as follows:
``It is an error to adjust an array that was not created with the
:adjustable argument non-nil. Therefore the results are undefined.
Therefore an implementation can define the behavior. Therefore, it is
ok to adjust an array created with the :adjustable argument nil.''
I want to prevent this. It's ok for your implementation to document that
the results are harmless, but I would prefer that you not state what they
are.
The other comments look good and duplicate a lot of Moon's comments, virtually
all of which are being incorporated. I expect the same will be true here.
Thanks, Pavel.
-rpg-
∂23-Oct-87 0845 @Score.Stanford.EDU:kempf%hplabsz@hplabs.HP.COM Re: Constructors
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 23 Oct 87 08:45:08 PDT
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Fri 23 Oct 87 08:38:40-PDT
Received: from hplms2 by hplabs.HP.COM with SMTP ; Fri, 23 Oct 87 08:44:31 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 23 Oct 87 08:44:09 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 23 Oct 87 09:43:42 pdt
To: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Constructors
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 21 Oct 87 13:57:03 -0500.
<2770829823-15823760@Jenner>
Date: Fri, 23 Oct 87 08:43:39 PDT
Message-Id: <21284.562002219@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Most programmers will want to name their constructors in a way which
> is reflective of their function, to construct a particular class. Thus,
> if they change the class name, it would make sense to change the
> constructor name, so that the name continues to reflect the function.
> Whether they change a constructor function name or a class name in
> a MAKE-INSTANCE form makes little difference. Thus, for the price of
> yet another DEFCLASS construct, you get very little in the way of
> additional abstraction. And, as has been argued, programmers who
> want to do this will do it anyway. Most programmers are going to
> want to do things like:
>
> (defun make-bar-foo (widgits)
>
> (make-instance 'foo :name 'bar :number-of-widgits widgits))
> You do that by adding the following option in the defclass:
> (:CONSTRUCTOR make-bar-foo (number-of-widgits &aux (name 'bar)))
I guess this example sums up the problem I have with the constructors
proposal as it stands. The semantics outlined in the original basenote
seem good, I guess I just don't like the syntax.
As a further example, consider if the programmer wants both a constructor
to make an instance with WIDGITS given and one with the name. Then the
DEFCLASS form would have to contain another :CONSTRUCTOR, with another
lambda list. One of the reasons I like Lisp over other languages is
because of the syntactic simplicity. The DEFCLASS form is already
syntatically fairly complex.
> This option is textually close to the initargs declaration, which is
> another advantage over a separate constructor function.
One could make this same argument about slot names and methods, that
the method definitions should be textually close to the slot definitions.
In fact, some Smalltalk programmers have made this argument, since this
is so in Smalltalk.
What would be the problem with having a seperate form to declare
constructors (other than incompatibility with DEFSTRUCT)? This could
even give the programmer more flexibility during the debugging phase,
since a programmer could more easily trace the "interpreted" or long
form of instantiation while debugging, then add the constructor afterwards,
during optimization, without having to modify the DEFCLASS form. While
debugging, a simple function could serve as the abstract interface.
jak
∂23-Oct-87 1041 @STONY-BROOK.SCRC.Symbolics.COM,@EUPHRATES.SCRC.Symbolics.COM:Moon@STONY-BROOK.SCRC.Symbolics.COM Comments on (the skeleton of) Chapter 3
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 10:41:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 262020; 23 Oct 87 13:42:31 EDT
Date: Fri, 23 Oct 87 13:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on (the skeleton of) Chapter 3
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871023174232.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is my final set of initial comments on this draft of the document.
Soon, probably later today, I will send out comments based on checking
the document against my list of decisions that I think we have reached.
3-5 says the value of CHECK-INITARGS is an initialization argument list,
but 1-39 says the value is ignored. I prefer 1-39.
================
3-6, 3-9 Purpose: We have a problem with class-direct-initargs for
method-implemented initargs defined by allocate-instance methods on
individuals. This is because methods on individuals don't conform to
the usual rule of thumb that the applicable methods for a class are the
union of the applicable methods for it and its superclasses.
After some thought, I think the right approach is to leave
class-direct-initargs the way it is, but change class-all-initargs not
to be defined in terms of class-direct-initargs. Instead
class-all-initargs should be defined in terms of the union of two sets:
- the result of mapping car over class-all-slot-initargs (which in
turn is defined in terms of class-direct-slot-initargs of the class
and its superclasses)
- the union of the mapping of method-keyword-names over the result of
compute-applicable-methods.
================
3-7 Purpose: I think we should say explicitly why both the function and
the form are present. The form is only there for documentation; it is not
legitimate to try to evaluate it, since you don't have the accompanying
lexical environment. The function is there to be called. I suppose it's
not really necessary to say that the function's body might not really be
the default value form, for instance the function might be a closure of
a predefined function with the default value form in its environment, in
some cases.
3-10 Purpose: ditto
================
3-12 Values: I think the same disclaimer about modifying the returned value
used by class-all-initargs and so forth should appear here. See typos
in that disclaimer noted below.
================
3-16, 3-17, 3-18: I think the same remark about why the -class- argument
is present should appear here as appears at the bottom of page 2-69.
Also we ought to say explicitly that these functions exist to be called
by the chapter 2 functions of similar names (except when they get
optimized out at compile time).
================
OPEN ISSUES:
3-14: I think Gregor wanted to do finalize-inheritance differently, so I
won't try to do a full rewrite on this now, I'll just respond to the questions
in brackets. This should make the writeup a little better, although it still
won't be up to the standard of the earlier portions of the document.
I don't know a much more precise definition of "when anything relevant changes."
I guess this gets called whenever the slots, slot descriptions, default initargs,
or direct superclasses of the class or any of its superclasses is changed,
and finalize-inheritance has already been called at least once for the class.
In addition, it gets called when a method is added, removed, or has its
keyword argument names changed. I'm not sure whether this applies to methods
for all generic functions, or just for the initialization generic functions.
Maybe that's up to each generic function to decide? Right now in Flavors,
something analogous is called whenever the class or any of its superclasses
is redefined in any way, or if an initialization method is defined, redefined,
or undefined. We don't actually bother with the optimization of trying to
detect redefinitions that don't actually change anything.
Also perhaps it wasn't clear that this function is called by the system,
not intended to be called by the user, and is intended to have methods
written by the user.
Last purpose paragraph should be: The system-supplied methods for
finalize-inheritance conspire with the system-supplied methods for
make-instance, default-initargs, check-initargs, allocate-instance, and
initialize-instance to speed up object creation by precomputing some
information and storing it in slots of the class. This optimization
is implementation-dependent, but the finalize-inheritance mechanism that
makes such optimizations possible is standardized.
The -class- argument is a class, not a class name.
The returned value is ignored.
The Remarks field seems okay as it stands. We can't be more specific about
"things" because these are determined by the user's special optimization needs,
not something we know in advance.
================
TYPOS:
3-4 Remarks: "customize the behavior allocate-instance", add "of"
3-5: ditto
3-6 Purpose: "given calss"
3-6 Arguments: "argument" should not be in italics.
3-6 Values: "including the name", add "s".
3-6 Remarks: "undefined if the values returned by this function are modified",
I think should be "undefined if the value returned by this function is modified".
Second remarks sentence ditto. Also I think the two sentences should be in a
single paragraph.
3-7, 3-8, 3-9, 3-10, 3-11 Remarks: ditto
3-8 Purpose line 3: "followed by the name of all slots", "name" -> "names"
3-11 ditto
3-9 Purpose line 4: "that defined" -> "that were defined"
3-13 Purpose line 1: ":default-initarg", add "s"
3-13 Remarks line 1: "customize the behavior default-initargs", add "of"
3-14 Arguments line 2: "whenthe"
3-15 Purpose lines 1,2: "keywords names" -> "keyword names"
3-15 Purpose line 2: "specificers"
3-15 Purpose line 3: "instand"
================
∂23-Oct-87 1055 Moon@STONY-BROOK.SCRC.Symbolics.COM Extent
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 10:55:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262042; Fri 23-Oct-87 13:56:18 EDT
Date: Fri, 23 Oct 87 13:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Extent
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 22 Oct 87 15:27 EDT from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871023175612.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Dick, I hear your "black box" argument, but I don't buy it. The
code that returns a closure of CALL-NEXT-METHOD, should someone
do that, must be on the inside of the box, i.e. lexically inside
a method.
It's probably not productive to spend any more time discussing
this right now.
∂23-Oct-87 1123 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Comments on comments on Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:23:26 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262069; Fri 23-Oct-87 14:23:51 EDT
Date: Fri, 23 Oct 87 14:23 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Comments on comments on Chapter 1
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871022-145609-5495@Xerox>
Message-ID: <19871023182352.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 22 Oct 87 14:56:04 PDT
From: Pavel.pa@Xerox.COM
I think that there's no qualitative difference between the argument
:OVERWRITE to the :IF-EXISTS parameter of OPEN and the argument VARIABLE
to the second parameter of DOCUMENTATION.
An important difference is that the latter is extensible and the former is not.
CLtL doesn't say DOCUMENTATION is extensible, but of course that's a bug, since
application developers are just as likely as Lisp implementors to develop new
types of named things to which they would like to attach documentation. Any
time multiple people are adding names to a namespace, we'd like to use packages
to organize that namespace. (The fact that package names are a flat namespace
rather than a hierarchy is an obvious compromise, or defect, here.)
Yet, in Common Lisp, one of
these is required to be a keyword and the other is required to be in the
LISP package. I think that there are a lot of these kinds of symbols
that should all have been keywords.
There are probably some mistakes of this type in Common Lisp, but in the
case of DOCUMENTATION, I think it's right not to use keywords. However,
I think the word should have been DEFVAR (as it was in Zetalisp, from
which Common Lisp copied this feature) rather than VARIABLE, to avoid
introducing a new symbol unnecessarily.
The original subject was whether the name of the standard method
combination type should be STANDARD or :STANDARD. I think the above
discussion doesn't really reflect on this, since we aren't proposing
to make all names of method combination types be keywords, so I'd
be content with either of those names.
∂23-Oct-87 1127 Pavel.pa@Xerox.COM Class naming
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:27:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 11:23:36 PDT
Date: Fri, 23 Oct 87 11:22:58 PDT
From: Pavel.pa@Xerox.COM
Subject: Class naming
To: Common-Lisp-Object-System@SAIL.Stanford.edu
Message-ID: <871023-112337-1027@Xerox>
On page 1-6 of the draft, there is the following paragraph:
A class can have a -name-, which is a symbol. The function CLASS-NAME
takes a class object and returns its name. The name of an anonymous
class is NIL. The function SYMBOL-CLASS takes a symbol and returns the
class associated with that symbol. We say that a class C has a -proper
name- S if C = (SYMBOL-CLASS S). Notice that it is possible that C /=
(SYMBOL-CLASS (CLASS-NAME C)).
I interpret this paragraph to mean that after the following code
executes, the class C has two proper names, ONE and TWO:
(let ((c (make-instance 'standard-class ...)))
(setf (symbol-class 'one) c)
(setf (symbol-class 'two) c))
Is this really the intent of the paragraph? I would hope not; there's
nothing particularly `proper' about that arrangement. I hope that the
paragraph really means to say that S is the -proper name- of a class C
if and only if S = (CLASS-NAME C) and C = (SYMBOL-CLASS S).
If this were the operative definition, then one could indeed say, as the
draft does in several places, "the proper name of C", since there would
be at most one such name.
Is this what's really meant on page 1-6?
Pavel
∂23-Oct-87 1133 Pavel.pa@Xerox.COM Re: Pavel's Comments
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 11:33:28 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 11:34:11 PDT
Date: Fri, 23 Oct 87 11:34:04 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Pavel's Comments
In-reply-to: "RPG@SAIL.Stanford.EDU's message of 22 Oct 87 22:52 PDT"
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-113411-1057@Xerox>
Me: Page 1-4, second set of bullets, second bullet -- Can't valid
programs
rely on that error being signalled if they also specify (SAFETY 3)?
I'm
generally unhappy with the phrase "at least in code compiled under
one
compiler safety optimization level". I'd prefer a direct statement
that
that level is 3.
Dick: I don't to make CLOS depend on things that might change in Common
Lisp
if I don't have to. Why state ``3'' when ``at least one'' will do?
Because I want to be able to write portable code that depends upon that
error being signaled. Saying ``at least one'' allows some bozo
implementor to decide that not signalling the error is safer than
signalling it and thus a higher safety number might turn off the
signalling. If you don't like using the number 3, how about ``at least
in code compiled under the highest compiler safety optimization level''?
Dick: I have heard people argue as follows:
``It is an error to adjust an array that was not created with the
:adjustable argument non-nil. Therefore the results are undefined.
Therefore an implementation can define the behavior. Therefore, it
is
ok to adjust an array created with the :adjustable argument nil.''
I want to prevent this. It's ok for your implementation to
document that
the results are harmless, but I would prefer that you not state
what they
are.
Why do you want to prevent this? You seem to be saying that an
implementation can't choose to implement all arrays as fully general
arrays unless they arrange for adjust-array to fail in some way on
arrays that were not originally declared to be adjustable. This seems
like a gratuitous failure. We already say that ``No valid program can
cause this situation to happen'', why not leave it at that? Since the
phrase ``but they must remain undefined'' is meaningless, I don't see
what it adds to the description.
Pavel
∂23-Oct-87 1206 Moon@STONY-BROOK.SCRC.Symbolics.COM Re: Pavel's Comments
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 12:06:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262146; Fri 23-Oct-87 15:07:13 EDT
Date: Fri, 23 Oct 87 15:07 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Pavel's Comments
To: Pavel.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871023-113411-1057@Xerox>
Message-ID: <19871023190715.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Fri, 23 Oct 87 11:34:04 PDT
From: Pavel.pa@Xerox.COM
If you don't like using the number 3, how about ``at least
in code compiled under the highest compiler safety optimization level''?
This sounds right to me.
On the adjust-array example, I would certainly oppose redefining
adjust-array of an array created with :adjustable nil to be "the results
are undefined" rather than "may be extended" as it is now. However, I
think Dick is right that there may be some circumstances in which
extensions should be forbidden, and I am certain that he is right that
we should stop confounding "the results are undefined" with "may be
extended."
∂23-Oct-87 1240 RPG Pavel
To: common-lisp-object-system@SAIL.Stanford.EDU
The paragraph about proper names was miswritten. I should read
``... We say that a class C has a proper name S if
S=(class-name C) and C=(symbol-class S). Notice that it is possible
that C\neq (symbol-class (class-name C)).'''
-rpg-
∂23-Oct-87 1247 RPG Undefined Definition
To: common-lisp-object-system@SAIL.Stanford.EDU
Pavel writes:
``Why do you want to prevent this? You seem to be saying that an
implementation can't choose to implement all arrays as fully general
arrays unless they arrange for adjust-array to fail in some way on
arrays that were not originally declared to be adjustable.''
I feel like Bork; does Pavel feel like Biden? I was not arguing
about arrays, I was arguing about the reasoning process used in this
case about arrays. If a specification says that ``it is not permissible
to do something'' or that ``one must not do something,'' then I expect
that it is not proper reasoning to turn that into ``it is permissible
to do something'' or ``it's perfectly ok to do something.''
Therefore, along with the other 3 error terms - which cover the vast majority
of all cases written about in the specification - I included the plug for
this hole.
-rpg-
∂23-Oct-87 1250 RPG Adjustable Arrays and Error Terminology
To: common-lisp-object-system@SAIL.Stanford.EDU
In fact, I would state the condition for adjusting non-adjustable arrays
to be that in the case where an attempt is made to adjust an array not
created to be adjustable, the behavior is extendable, which is what
implementors have chosen to do here.
-rpg-
∂23-Oct-87 1333 Bobrow.pa@Xerox.COM Comments on Chapter 1
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 13:33:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 13:34:20 PDT
Date: 23 Oct 87 13:33 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Comments on Chapter 1
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-133420-1308@Xerox>
As with other commenters, I am impressed with the general high level of
quality of the chapter. I have tried to leave out those comments
already made by Moon, Sonya and Pavel, and others of my comments that I
have sent out.
1-3 Para 4. The terminology of "a generic function can be specialized
by the definition of methods" may be confusing -- since it is not
necesarily the case that what is added is more special -- specialized in
the sense that classes are specialized. Methods can be completely
independent of ones added before. How about "a generic function can be
extended by the addition of methods". Also in that paragraph and below,
the terminology of "class-specific operations" ignores individuals.
Perhaps better would be "parameter-specialized operations"
p 1-6 It might mention after the third paragraph that "A class can be
given a name by using
(setf (symbol-class <symbol>) class), but that this does not guarantee
that the class-name of class is <symbol>. A class may also have more
than one name, at most one of which is its proper name.
In the paragraph about a class precedence list being consistent with its
local precedence order, it is worth making it explicit that subclasses
always precede their supers (although that is implicit in your
definition of local precedence list)
p 1-7 para 2 you say "CLOS provides a default metaclass that is
appropriate for most programs." Please add "The default metaclass is
called standard-class." so that later we can refer to it.
p 1-8 "Slots can be accessed in two ways: by use of METHODS defined by
the defclass form, added to the appropriate generic function, and by
use of the primitive function slot-value."
A sentence here about why one defines these accessors may be in order.
"These accessors provide a more abstract interface for external users of
instances of a class. It allows implementors to later change the
definition of a class, removing the slot, but providing a method that
implements the functionality formerly captured structurally."
I support the removal of the sentence with the phrase "individual slots"
p1-9 Sometimes it is convenient to access slots from within the body of
a method or function ** simply by using the name of the slots as if they
were variables. **
p1-11 :reader :accessor paragraph. To make things more explicit, add
"If a slot specifier contains a reader or accessor option, the specified
methods are created only in the class in which the slot specifier
explicitly appears."
"A consequence of the type rule ..." Add at the end "It is an error to
assign a value to a slot that does not satisfy the type constraint."
p 1-13 There is a mention of :constructor here. We agreed to postpone
decision on constructors. I would like to see all mention of
constructors disappear from this version of the spec until agreement is
reached.
Paragraph "Note that redefining ..." The last sentence would be better
as the third sentence of that paragraph.
Last paragraph should have sentence "If there is a shared slot in the
old class definition that has the same name as a local slot in the new
class definition, the local slot in every updated instance is eql to the
value that was in the shared slot.
p1-14 "The Object System guarantees that ..." references to being
defined by defclass should be replaced by being instances of
standard-class. We have talked about mechanisms that undercut this
defclass condition, so the level of indirection is better. This is a
specification, and it is the metaclass that will count for this
guarantee.
p1-15 Changing the class of an instance
"to conform to the definiton of the SPECIFIED class."
Paragraph 2 ought to be after paragraph 3, and have a sentence added,
"This initialization is done by the default method on the
generic-function class-changed.
Para 5 should be deleted. The interesting sentence that might be added
is the one I wrote above (p1-13) for shared slot to local slot updating.
p 1-16
I have sent out a comment on this, and hope we can get rid of the
standard-type-class notion in favor of "built-in-class" as a metaclass
and "Common Lisp data type class" as a descriptive term.
I think we should put in the spec something about package stream etc,
saying that we expect them to be forced to be distinct types, and
include them as Common Lisp data type classes.
p1-18
Why is (c,c) for classes in SC added to R. This means there is never a
situation in which there is no pair in the ordering that has some
specific c as its right hand element. I am missing something I am sure.
p 1-21 in with-added-methods, we had better specify here that these are
copies of methods in the lexically visible generic function, or we may
get unwanted side effects.
p1-22 para 2 It should say that an error is signalled if there a
defgeneric is evaluated, and the name is bound to a non generic
function.
"the lambda list of the generic function is CONSTRUCTED to be congruent
with the lambda-list of the new method.
p1-23 Can both (EQL form) and (EQL object) be Common Lisp type
specifiers. The first is what is the name, the second is what is
described below. On the next page it says both parameter specializers
and parameter specializer names must be CL type specifiers.
p1-25 Point 4 "in in" --> "in"
p 1-28 Mention next-method-exists-p here (I like Pavel's suggested name
change)
p 1-33 Question about standard-type-class again. We need a different
statemetn about structure-class (I could easily imagine a CL that made
it a subclass of standard-class)
p1-35 Top line. It is not true for all metaobject programming that the
arguments are classes e.g. methods on generic-fucntion and methods. So
it should be clear here that you mean metaprogramming with respect to
initialization.
p1-38 "(This is true even if a :before method ..." This should say "if
any code has stored a slot value before the default method is run. e.g
:around, more specialized primaries using call-next-method as well as
:before.
p1-39 Is unitinitialized state better than unbound. The latter agrees
with the function names.
There is the error condition missing from the make-instance symbol case
in case the symbol is not a class-name. At least a comment ought to be
made.
∂23-Oct-87 1445 Pavel.pa@Xerox.COM Re: Undefined Definition
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 14:45:25 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 23 OCT 87 14:42:27 PDT
Date: Fri, 23 Oct 87 14:42:21 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Undefined Definition
In-reply-to: "RPG@SAIL.Stanford.EDU's message of 23 Oct 87 12:47 PDT"
To: common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871023-144227-1427@Xerox>
Dick: I feel like Bork; does Pavel feel like Biden?
I think that I'm stating my opinions in my own words, so I guess I can't
feel like Biden ...
Ahem.
Dick: If a specification says that ``it is not permissible
to do something'' or that ``one must not do something,''
then I expect that it is not proper reasoning to turn that
into ``it is permissible to do something'' or
``it's perfectly ok to do something.''
I think there's a confusion here between the specification of valid
programs and the specification of valid implementations. I guess I
can't envision a case in which I actually want to forbid an
implementation to provide a useful semantics in one of these undefined
situations. I have always interpreted the "is an error" cases as
breathing space for the implementations, since they don't have to detect
the situation or signal an error, and a warning to the programmer not to
count on any particular semantics or harmlessness.
More concisely, can you give an example of a situation that you strongly
prefer to have in the undefined category rather than the "may be
extended" category?
Pavel
∂23-Oct-87 1457 Moon@STONY-BROOK.SCRC.Symbolics.COM More comments on the draft document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 14:57:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262376; Fri 23-Oct-87 17:58:39 EDT
Date: Fri, 23 Oct 87 17:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More comments on the draft document
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <19871023215825.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Additional comments resulting from comparing the document to my
clos-decisions file and the 87-002 amendments handout:
We need to note somewhere that SYMBOL-FUNCTION, FBOUNDP, and
FMAKUNBOUND take an optional environment argument, just like
ENSURE-GENERIC-FUNCTION, SYMBOL-CLASS, CBOUNDP, and CMAKUNBOUND.
This is necessary to be able to find a generic function object,
given its name, in the compile environment. FMAKUNBOUND may
be just for consistency, but FBOUNDP and SYMBOL-FUNCTION are to
allow ENSURE-GENERIC-FUNCTION to work.
Add to Remarks fields: The body of (DEFMETHOD -name- ...) is surrounded
by an implicit block named -name-, if that is a symbol, or -name1-, if
-name- is (SETF -name1-), by analogy with DEFUN. The same applies to
methods defined by the :METHOD option to DEFGENERIC, GENERIC-FLET,
GENERIC-LABELS, and WITH-ADDED-METHODS. There is no implicit block around
the body of a method defined by the :METHOD option to GENERIC-FUNCTION.
What can be done with method objects, e.g. can one method be added
to more than one generic function?
Gregor: I believe it should signal an error to attempt to put a method on more
than one generic function. My model of this is that if you want to do
something like that, you can take one function, use it as the method function
of multiple methods, each of which would be on a different generic function.
September: Agreed.
I don't see anything about this in the document. Should the discussion under
make-instance of how to make a method require a :generic-function initarg?
Or should there be a remark under add-method saying it can signal an error
if the method is already claimed?
Which symbols defined by the standard go in what package? I think we need to
say explicitly that we have postponed a decision on this.
2-20 second paragraph: delete "from their superclasses and so on", or
else change "superclasses" to "direct superclases". As written it doesn't
make sense, since a superclass of a superclass of C is always a superclass
of C, and might encourage confusion about the difference between a superclass
and a direct superclass.
2-65 Same comment that the value is always eq to the first argument as on 2-6
and 2-10.
∂23-Oct-87 1550 Bobrow.pa@Xerox.COM More on Class names
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 15:50:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 15:43:03 PDT
Date: 23 Oct 87 15:42 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <871023-154303-1550@Xerox>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
∂23-Oct-87 1633 Moon@STONY-BROOK.SCRC.Symbolics.COM More on Class names
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Oct 87 16:33:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 262473; Fri 23-Oct-87 19:34:48 EDT
Date: Fri, 23 Oct 87 19:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <871023-154303-1550@Xerox>
Message-ID: <19871023233437.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 23 Oct 87 15:42 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
I agree.
∂23-Oct-87 1716 Masinter.pa@Xerox.COM Environment-arguments, MACRO-FUNCTION-ENVIRONMENT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 17:16:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 OCT 87 17:17:25 PDT
Date: 23 Oct 87 17:17 PDT
From: Masinter.pa@Xerox.COM
Subject: Environment-arguments, MACRO-FUNCTION-ENVIRONMENT
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Fri, 23 Oct 87 17:58 EDT
To: Common-Lisp-Object-System@sail.stanford.edu
cc: CL-Cleanup@Sail.stanford.edu
Message-ID: <871023-171725-1686@Xerox>
Moon (on CLOS list):
"We need to note somewhere that SYMBOL-FUNCTION, FBOUNDP, and
FMAKUNBOUND take an optional environment argument, just like
ENSURE-GENERIC-FUNCTION, SYMBOL-CLASS, CBOUNDP, and CMAKUNBOUND.
This is necessary to be able to find a generic function object,
given its name, in the compile environment. FMAKUNBOUND may
be just for consistency, but FBOUNDP and SYMBOL-FUNCTION are to
allow ENSURE-GENERIC-FUNCTION to work."
Related issues were discussed at some length on CL-CLEANUP. If someone
wants to write this up for cleanup, I have a file of the discussion
(under GET-SETF-METHOD-ENVIRONMENT in Jan-87 and ENVIRONMENT-ARGUMENTS
in April 87).
There seems to be a number of separable issues, but separating them is
difficult. Volunteers appreciated.
∂23-Oct-87 1851 Gregor.pa@Xerox.COM status of "object" or "standard-object"
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Oct 87 18:51:05 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 OCT 87 18:46:58 PDT
Date: Fri, 23 Oct 87 18:46 PDT
From: Gregor.pa@Xerox.COM
Subject: status of "object" or "standard-object"
To: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <871014112750.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <871023184641.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Wed, 14 Oct 87 11:27 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Last month we discussed whether CLOS should specify the class "object"
or "standard-object", and we didn't get anywhere.
To me, this seems to be a hole in the spec that we ought to fill up in
time for the next draft. It seems like most people believe there will
be one or more of these classes, but the spec doesn't say anything at
all about them. Unless we do something, our draft will imply that
there won't be these classes, but we will still be assuming there will
be.
In fact I think this hole manifests itself in several places. Specifically,
there are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
object (or standard object)". The examples of this I can find right now
are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
standard-class, so they should be on the class object, thats what its
there for.
Other examples of where a particular implementation might want to have a
method on OBJECT as well as one on T are:
print-object (pg 2-63)
describe (pg 2-39)
So I think we have to include this class (I don't particularly care
about the name), and fix the places I have mentioned to refer to it.
-------
∂26-Oct-87 1032 @RELAY.CS.NET:DUSSUD@jenner.csc.ti.com "Object" Class.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 26 Oct 87 10:32:17 PST
Received: from relay2.cs.net by RELAY.CS.NET id af11653; 26 Oct 87 9:50 EST
Received: from csl.ti.com by RELAY.CS.NET id ab07103; 26 Oct 87 9:47 EST
Received: from Jenner by tilde id AA24621; Mon, 26 Oct 87 07:44:36 CST
Message-Id: <2771243079-7629931@Jenner>
Date: Mon, 26 Oct 87 07:44:39 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: "Object" Class.
In-Reply-To: Msg of Fri, 23 Oct 87 18:46 PDT from Gregor.pa@xerox.com
In fact I think this hole manifests itself in several places. Specifically,
there are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
object (or standard object)". The examples of this I can find right now
are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
standard-class, so they should be on the class object, thats what its
there for.
Other examples of where a particular implementation might want to have a
method on OBJECT as well as one on T are:
print-object (pg 2-63)
describe (pg 2-39)
So I think we have to include this class (I don't particularly care
about the name), and fix the places I have mentioned to refer to it.
I agree.
Patrick.
∂26-Oct-87 2146 COMMON-LISP-OBJECT-SYSTEM-mailer Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Oct 87 21:45:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264295; Tue 27-Oct-87 00:04:48 EST
Date: Tue, 27 Oct 87 00:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871027050430.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 26 Oct 87 1130 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
Note: I haven't looked at today's draft yet. But here are some comments
on open issues, some of them based on talking with Danny Bobrow and some
of them based on questions from Dick Gabriel.
1. What is the story on the idea of built-in?
The key point here is that CLOS does not specify exactly which types are
built-in. We split "standard type class" into two things: the types
that are defined in Steele's book, which are candidates for being
built-in, and the built-in-class metaclass, which defines the ones that
actually are built-in in a given implementation. So we're allowing any
Common Lisp data type to be either built-in or a standard-class in a
particular implementation, but you can check the metaclass to see if it
is built-in. Also we're allowing implementations to make new
implementation-dependent built-in types, so the only thing that's
guaranteed -not- to be built-in are the standard classes you define
yourself. Also the structure classes I guess.
Danny points out that in the future we might want to make an incompatible
change to Common Lisp to require some particular type that is already in
Steele's book to be a standard-class rather than a built-in-class, whereas
in the initial version of CLOS this will be at the implementation's option.
For instance, one might want to do this to streams. Moon speaking again:
I don't see any CLtL types that are indubitably candidates for this, so
I think we can put off that issue.
It's implied by a paragraph on p.1-17, but it could be made clearer
in the commentary on Figure 1-1 that there can be additional,
implementation-dependent elements in the class precedence lists
of these types. CLOS only requires that the elements listed by
present and be in the order specified.
I'll try to send out in a separate message a cleanup of the built-in-class
message that Danny and Gregor sent, to be more appropriate to go into the
document. It's late, I guess that message won't go out until Tuesday.
2. UPDATE-INSTANCE-STRUCTURE and CLASS-CHANGED needed to be parallel
in how and who does initialization. Danny proposes that default primary methods
handle it in both cases. My view is that unless there is some meta-object
way to eliminate the initialization step, the only way is by putting
them into a primary method that can be shadowed or eliminated.
In talking to Danny last night, I came to believe that he thinks there
would be no meta-object way to get at the initialization in this step.
Actually, all of UPDATE-INSTANCE-STRUCTURE, CLASS-CHANGED, and
INITIALIZE-INSTANCE can usefully be consistent. This means that
for all three of these the default primary method is in charge of
initializing newly added slots that are not already initialized,
by evaluating the :initform and storing the result into the slot.
For UPDATE-INSTANCE-STRUCTURE and CLASS-CHANGED, values of slots
that already existed are transported into the updated instance
by something "at the bit level", before the generic function is
called. All three of these default primary methods are permitted
to conspire with the bit level to optimize out initforms that
neither produce nor depend on side-effects, by storing them into
the slots before the generic function is called rather than in the
default primary method. This optimization is still valid, but
not useful, when the default primary method has been shadowed.
Also implementations are permitted to open-code the body of the
default primary method in a way that makes it customized to a
specific class, rather than being forced to obtain information
from the class object and interpret it. However, this does not
change the user's ability to shadow the default primary method,
thus this optimization has to be done by open-coding rather than
by automatically generating a customized method on a more specific
class than STANDARD-OBJECT (I think this is grotesque, but it's the
only way to preserve the property that apparently people find highly
desirable of being able to turn off the evaluate-the-initforms
behavior without using a :AROUND method to turn everything off).
Changes from what we have now:
INITIALIZE-INSTANCE is not changed
UPDATE-INSTANCE-STRUCTURE -- the first bullet in the Remarks goes
away. Preserving the values of old slots is done at the bit level.
CLASS-CHANGED -- responsibility for evaluating the :initforms moves
from CHANGE-CLASS to CLASS-CHANGED (in the latest version of the
document I have, chapters 1 and 2 are inconsistent about this).
Responsibility for the rest of the structural transformation
remains with CHANGE-CLASS.
I think this shows that the use of standard method combination is wrong
for all three of these, because we have to keep telling people "don't
use :before methods, you'll be surprised, and don't use primary methods
unless you really mean to shadow the primary method." However, I know
I'm not going to change any minds on that point. If I was designing
this in a vacuum, I think I would make all three of these use PROGN
:MOST-SPECIFIC-LAST method combination, and then the user would not be
able to tell, except by using :AROUND methods, whether the initforms
are done by the default primary method or by the caller, and there
would be no way to write a method that does something unexpected,
so we wouldn't have to warn people about pitfalls.
3. What's the resolution on the CPL for NULL, SYMBOL, LIST et al?
The only one that's broken is the CPL for NULL. Either (null symbol list
sequence t) or (null list sequence symbol t) would be acceptable to me
and to Danny; the real problem is the (null list symbol sequence t) that
we have now. But we could say that was just a typo. Danny said he wanted
to check with Gregor in case G. had any strong opinion. I notice the
latest draft has (null symbol list sequence t) and I'm willing to live
with that.
4. What terminology for ``default primary method'' should we use?
We should define a class named STANDARD-OBJECT (this was the best name
Danny and I came up with), which is the least specific class, except for
T, in the CPL of any instance whose meta-class is STANDARD-CLASS. The
reason for existence of STANDARD-OBJECT is to allow there to be default
methods for instances of standard classes, that don't apply to instances
of other classes (built-in, structure, what have you). I hope with some
tweaking of the English the above paragraph can go into the document.
Most of the CPL examples will need to have STANDARD-OBJECT added to them.
There are several places in the spec which refer to the "default primary
method" when in fact they should be referring to the "primary method on
standard-object". The examples of this I can find right now are:
update-instance-structure (pg 1-13)
class-changed (pg 1-15)
initialize-instance (pg 1-34)
(For class-changed, we have to say which parameter is specialized.
I think the answer is, "both").
The point in these examples is that these "system supplied" methods are
actually providing default behavior for instances with metaclass
STANDARD-CLASS, so they should be on the class STANDARD-OBJECT, that's
what it's there for.
It's also likely that an implementation would want STANDARD-OBJECT
methods for PRINT-OBJECT and DESCRIBE, in addition to the T methods.
However, for these generic functions we say only that there is always
an applicable method, we don't say how the system-supplied methods
are modularized.
(Above text was Bidenized from Gregor in part.)
5. Are methods side-effected when method functions change?
One issue is, why should methods be different from classes and generic
functions? Both defclass and defgeneric side-effect an existing object,
they don't create a new object if there already is one with the name.
Another issue seems to be what happens if an error is signalled, e.g. due
to noncongruent lambda lists? Has the existing method object already
been side-effected when that happens? In general, CLtL never says what
the state of the program is at the time an error is signalled, and would
allow an implementation to choose whether to do the error-checking first
or the side-effects first. However, we might want CLOS to be a bit
cleaner. I don't see any reason not to do the error checking before the
side-effects.
We should see if Gregor comes up with some reason at the meta-object level
why it's really important that methods be inconsistent with generic functions
and classes. But in the absence of that, I think we ought to say that
defmethod side-effects an existing method object. We haven't said what
the macro expansion of defmethod is exactly, and perhaps that's meta-object
level business, but I think it might involve a function similar to
ensure-generic-function that takes enough keyword arguments to describe
the method, and either makes a new object or updates an existing one.
6. The reason that DEFMETHOD shouldn't specialize functions like CAR defaultly
is that the compiler has already compiled a pile of stuff knowing what's up.
WITH-ADDED-METHODS created lexical environment in which the compiler can know
all about that gives. Therefore, I think that if WITH-ADDED-METHODS is asked
to extend an ordinary function, it should make that function the method
function for the default primary method.
Another point is that this effect can be simulated with GENERIC-FLET, by
writing a default method that calls the old definition of the function
name. This suggest that there can't be much harm in allowing
WITH-ADDED-METHODS to do this. My only problem in evaluating this is that
I can't figure out what WITH-ADDED-METHODS is good for in the first place.
However I agree that WITH-ADDED-METHODS should be allowed to extend an
ordinary function.
7. What about the class named OBJECT? How does it fit in?
STANDARD-OBJECT, see above.
8. If CALL-NEXT-METHOD is globally bound to a function that signals
an error, the name CALL-NEXT-METHOD has indefinite scope. Is this
what we mean to say?
Well, the name has indefinite scope, but a particular binding of the name
to a useful value (not the global one that just signals an error) only has
lexical scope. I don't know the proper way to say this, but I think it is
what we mean to say.
By your comment about CALL-NEXT-METHOD's extent including the arguments
to the method, do you mean this:
(defmethod foo ((x1 c1) ... (xn Cn)
&optional (next-fun #'(lambda () (call-next-method))))...)
I guess this is ok.
Yes, that's what I mean. I guess the precise language would be that the
scope of the binding of CALL-NEXT-METHOD to a useful function includes
forms that appear in parameter specifiers of the defmethod, of course with
the exception of forms that appear in parameter specializer names of the
defmethod, since those latter forms are evaluated at definition time, not
at generic function call time.
Implementing this is epsilonically harder than allowing call-next-method
only in the body, but it seems to be what people will expect, and I'm
sure it's not enough harder to implement for implementation difficulty
to be a consideration.
By the way, this could also be written more simply
(defmethod foo ((x1 c1) ... (xn Cn)
&optional (next-fun #'call-next-method))...)
which is why we changed call-next-method from a macro to a function.
Another open issue is that initargs you have to pass to make-instance
when making a standard-method. I think the best bet is that in addition
to the initargs already documented, you must pass :lambda-list, which
is a lambda-list from which the implementation is permitted to derive
the number of required and optional arguments, the presence of rest/key
arguments, the keyword names, for lambda-list congruence computation.
An implementation is also permitted to ignore the :lambda-list argument
and get this information from the :function argument, if in that
implementation a lambda-list can be retrieved from a function (CLtL
doesn't require that). I think the lambda-list can be anything that
meets these requirements, so it can be the specialized-lambda-list that
appears in the defmethod form, or it can be an ordinary function lambda
list, or it can be the type of stripped down lambda-list that can
be used with defgeneric. I think it's better for the derivation of
lambda-list congruence information from lambda-lists to be in the system,
rather than being reimplemented by every user, hence I suggest a lot
of freedom in what kind of lambda-list the initarg can accept. The
alternative would be to require the user to pass two numbers, a boolean,
and a list of keyword names, but I'd rather not do it that way.
∂26-Oct-87 2202 Common-Lisp-Object-System-mailer Proof of CLOS Document
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 26 Oct 87 22:01:56 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 26 Oct 87 21:58:39-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 26 Oct 87 11:17:56 PST
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 26 Oct 87 11:17:14 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 26 Oct 87 12:16:43 pst
To: lgd@sail.stanford.edu, rpg@sail.stanford.edu
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Proof of CLOS Document
X-Mailer: mh6.5
Date: Mon, 26 Oct 87 11:16:40 PST
Message-Id: <1123.562274200@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Linda & Dick:
Compliments on the fine job you've both done! I had no trouble TeXing
the document, once I found out that LaTeX didn't work and I had to
use straight TeX.
I only had an opportunity to go through the document this weekend, so
these comments may not be in time for the November meeting, but I
wanted to post them anyway. For the most part, they are simple typos
or regularization of wording. I did not have time to read the
discussion last week (sorry) so there may be some duplicates here.
CHAPTER 1:
Overall: meta-object v.s. metaobject v.s. meta-class v.s. metaclass
Might it not be a good idea to stick to one meta notation
rather than using meta-object and metaclass?
pg. 1-7: Last sentence. Shouldn't this be pharased in terms of the
error terminology?
pg. 1-9: Second last line. "The macro WITH-SLOTS invokes the function
SLOT-VALUE is to access slots."
↑↑↑↑↑
Incorrect English.
pg. 1-11: Last line. "earliest in the class precedence list" Since the
class precedence list hasn't yet been introduced, perhaps "most
specific class" would be more approprate.
pg. 1-16: 4th Paragraph, 4th line. "Each standard type class has the
class STANDARD-TYPE as a metaclass"
↑↑↑↑
Implies there may be more than one. Perhaps "as its" would be better.
pg. 1-16: 4th Paragraph. Last sentence. Again, use of the error
terminology would probably be appropriate.
pg. 1-16: 6th Paragraph. Again, this looks like a forward reference
to the CPL.
pg. 1-17: Last Paragraph. It is not clear from this what should happen
if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
error be signalled or should the CAR of the list be used? On pg. 42 of
CLtL, the description of type specifiers which are lists suggests
that the CAR should work.
pg. 1-25: List item 4. Last sentence. "in in the generic function"
typo.
CHAPTER 2:
Overall: When referring to SETF functions, the list specifying a
SETF function name is often not quoted. Example: (fboundp (setf <name>)).
If the argument had been a function symbol name, however, it would have
been quoted, since FBOUNDP is a function and therefore the arguments
are evaluated. Shouldn't this be so for SETF function names as well,
or is the assumption that (SETF <name>) is a macro which returns the
actual name of the function (e.g. expands into something like '<actual name>)?
Perhaps using the italic <setf-function-specification> would be more
appropriate.
Overall: The criterion mentioned in the first chapter for whether a
generic function is part of the metaobject protocol (at least, the
impression I obtained after reading Ch. 1) was that the generic function
operated on class objects. There are, however, several functions
in Chapter 2 which have class arguments in their interface. Leaving
aside the obvious exceptions such as CLASS-NAME which are used heavily
during interactive development, reasons for others are not so obvious.
Should either the wording in Chapter 1 be tightened up to exclude the
exceptions, or should some of the functions in Chapter 2 which discriminate
on class objects be moved to Chapter 3?
pg. 2-7: Is CALL-NEXT-METHOD a function? From the as yet incomplete
e-mail discussion, it would seem to be either a macro (if Moon's
implementation is accepted) or a special form.
pg. 2-7: 2nd Paragraph under ARGUMENTS. "the same set of applicable methods"
I think what you mean here is the effective method, since, the intent is
to avoid having to recalculate the effective method.
pg. 2-21: 2nd Paragraph. Shouldn't this be phrased in terms of the error
language?
pg. 2-26: :DECLARE description. Why prohibit INLINE and NOTINLINE? One
optimization a compiler writer might want is to have the generic function
code inserted in line. Or is the assumption that this should be controlled
in the lexical context enclosing the generic function invocation, rather
than in the definition of the generic function's interface?
pg. 2-27: Top of page. If the class name given to the :METHOD-CLASS
and :GENERIC-FUNCTION-CLASS does not specify a class whose protocol
conforms to that required for a method or a generic function, is an error
signalled? Or are these options caveat empor?
pg. 2-30: Top of page. I'm curious if the form generated is expected to
be executable. That is, if <operator> can be a keyword symbol, then the
implicit assumption is that the function cell of keywords can be
bound. I know this is possible in Symbolics CL and not in ours, also
I don't think CLtL says anything either way. Is there a Cleanup proposal
on this?
pg. 2-32: Top of page. "semantic meaning". Redundant. Should be either
"semantics" or "meaning".
pg. 2-40: 2nd bullet item, last line. Do you mean list? (SETF <name>)
is something more than a general list, I think. Perhaps function
specification?
pg. 2-57: Last line. I believe this line is out of date, because
the extension to CALL-NEXT-METHOD was adopted (i.e. allowing arguments).
pg. 2-61: VALUES. Don't you mean T or NIL? There are no true and
false types in CL.
pg. 2-61: REMARKS. Wording on the first sentence is a little rough.
"...within the method within which it is referenced." might be better
phrased as "...within the method where it is referenced."
pg. 2-73: REMARKS. Last sentence. Wording is a little rough.
"...convert variable uses into calls to generic function" might be better
phrased as "...convert variable uses into calls to generic functions".
pg. 2-74: First sentence. "The generic function UPDATE-INSTANCE-STRUCTURE
is not intended to called by..."
???
Suggest adding a "be".
CHAPTER 3
Overall: There are a couple of function descriptions with the wording:
The results are undefined if the values returned by the
function are modified.
It is permitted, but not required, for an implementation
to return values that share with internal data structures.
In the context of what the results of invoking the function being
described are, the first sentence makes no sense, because, once the
function has returned a value, further "results" are not forthcoming:
the function has completed its task. I believe what is meant here
is that the results of further operations using the Object System
may or may not be impacted by modifying returned values, depending
on whether the implementation does or does not choose to return
a shared data structure.
pg. 3-6: 2nd Paragraph. Last Sentence. "class" is misspelled as
"calss".
pg. 3-12: SYNTAX. Shouldn't the argument list be an &REST parameter,
since its size will vary depending on the number of required arguments
the generic function accepts?
pg. 3-12: I'm confused by where the effective method is calculated.
Is it this function, or is there another?
pg. 3-13: PURPOSE. The implication of the first sentence is that
<initarg list> is modified, while the last sentence specifically forbids
that. Why not simply say in the first sentence that the initialization
arguments are appended to a copy of <initarg list>?
pg. 3-14: This is pretty vague.
pg. 3-15: 1st Paragraph. "instead" misspelled as "instand".
∂27-Oct-87 0845 Common-Lisp-Object-System-mailer Proof of CLOS Document
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 08:44:52 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264619; Tue 27-Oct-87 11:46:56 EST
Date: Tue, 27 Oct 87 11:45 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proof of CLOS Document
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <1123.562274200@hplabsz>
Message-ID: <19871027164545.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
A few comments on excerpts from your comments:
Date: Mon, 26 Oct 87 11:16:40 PST
From: kempf%hplabsz@hplabs.HP.COM
pg. 1-17: Last Paragraph. It is not clear from this what should happen
if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
error be signalled or should the CAR of the list be used? On pg. 42 of
CLtL, the description of type specifiers which are lists suggests
that the CAR should work.
Is this the page that has figure 1-1 on it? I can't find anything on that
page that looks like what you're referring to. I suspect you've uncovered
a problem here, but I can't find the problem. Note however that the
second paragraph on page 1-16, where it says (type-of I) is S if S is
the proper name of C, else C, should say that this only applies when C
is an instance of STANDARD-CLASS.
Overall: When referring to SETF functions, the list specifying a
SETF function name is often not quoted. Example: (fboundp (setf <name>)).
If the argument had been a function symbol name, however, it would have
been quoted, since FBOUNDP is a function and therefore the arguments
are evaluated. Shouldn't this be so for SETF function names as well,
or is the assumption that (SETF <name>) is a macro which returns the
actual name of the function (e.g. expands into something like '<actual name>)?
It's just missing quote marks; no hairy macro like that was intended.
Do you have page references for these typos? I think I noticed one or two,
but they're easy to overlook and you probably saw some that I missed.
Perhaps using the italic <setf-function-specification> would be more
appropriate.
That would be okay too, although offhand I think it would be better to
say '(SETF <name>) so we don't have to define one more syntactic
nonterminal symbol.
pg. 2-7: Is CALL-NEXT-METHOD a function? From the as yet incomplete
e-mail discussion, it would seem to be either a macro (if Moon's
implementation is accepted) or a special form.
CALL-NEXT-METHOD has been a function since we changed it from a macro
in late 1986 or early 1987. I'm not sure what implementation of mine
you're referring to; I don't recall proposing one this year. I proposed
one last year, which is totally out of date by now.
pg. 2-7: 2nd Paragraph under ARGUMENTS. "the same set of applicable methods"
I think what you mean here is the effective method, since, the intent is
to avoid having to recalculate the effective method.
No it really means the stronger condition that it says. Remember we spent a
long time discussing this. I don't remember all the discussion, but it may
have been that "same applicable methods" is both easier to specify precisely
and easier to compute than "same effective method".
pg. 2-26: :DECLARE description. Why prohibit INLINE and NOTINLINE? One
optimization a compiler writer might want is to have the generic function
code inserted in line. Or is the assumption that this should be controlled
in the lexical context enclosing the generic function invocation, rather
than in the definition of the generic function's interface?
Precisely. The idea is that there isn't any body in DEFGENERIC, so there
isn't any code for INLINE and NOTINLINE declarations to affect.
pg. 2-30: Top of page. I'm curious if the form generated is expected to
be executable. That is, if <operator> can be a keyword symbol, then the
implicit assumption is that the function cell of keywords can be
bound. I know this is possible in Symbolics CL and not in ours, also
I don't think CLtL says anything either way. Is there a Cleanup proposal
on this?
This moved to 2-29 in the latest draft (if things are getting shorter, that's
a good sign!). I don't see anything that implies here that an implementation
has to allow <operator> to be a keyword symbol. Certainly that was not
intended. On the other hand, I don't know of anything in CLtL that allows
implementations to forbid defining keyword symbols as functions. Anyway,
the intent here is that <operator> is the name of a function, macro, or
special form and can appear in the car of a form; precisely what objects
satisfy that criterion is defined by CL rather than CLOS.
pg. 2-40: 2nd bullet item, last line. Do you mean list? (SETF <name>)
is something more than a general list, I think. Perhaps function
specification?
(SETF <name>) is certainly a list, whatever else it is. But I note that
this is one the missing quote marks you mentioned earlier, which might
have obscured the meaning. (Page 2-39 in latest draft.)
pg. 3-12: SYNTAX. Shouldn't the argument list be an &REST parameter,
since its size will vary depending on the number of required arguments
the generic function accepts?
I don't think so, I think this argument is just a list of arguments.
pg. 3-12: I'm confused by where the effective method is calculated.
Is it this function, or is there another?
This function computes the applicable methods, not the effective method.
compute-effective-method is mentioned on 1-28, but there is no writeup
for it yet.
∂27-Oct-87 0852 Common-Lisp-Object-System-mailer status of "object" or "standard-object"
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 08:52:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264645; Tue 27-Oct-87 11:54:33 EST
Date: Tue, 27 Oct 87 11:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: status of "object" or "standard-object"
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871023184641.0.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871027165325.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
I assume there is a metaclass mechanism that allows a metaclass, such
as STANDARD-CLASS, to specify that each class that is an instance of
that metaclass or one of its submetaclasses shall contain a class,
such as STANDARD-OBJECT, as a superclass. Do we need to say anything
about that in chapter 1, or should we simply say that any standard
class has STANDARD-OBJECT and T in its CPL, without specifying how
exactly they get there?
∂27-Oct-87 1051 Common-Lisp-Object-System-mailer Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Oct 87 10:50:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 264818; Tue 27-Oct-87 13:52:38 EST
Date: Tue, 27 Oct 87 13:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871027050430.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871027185132.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 27 Oct 87 00:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 26 Oct 87 1130 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
1. What is the story on the idea of built-in?
I'll try to send out in a separate message a cleanup of the built-in-class
message that Danny and Gregor sent, to be more appropriate to go into the
document. It's late, I guess that message won't go out until Tuesday.
This turned out to be very much more difficult than I expected. At the next
level of detail behind Danny's message of 22 October, there is a great deal
of ill-definedness and unclarity. I'll try to send something out later today,
but there is an excellent chance that it will be delayed until tomorrow.
If in the process of writing it I end up convincing myself that built-in-class
is a bad idea after all, I'll try to send something out explaining the reasoning
that got me there.
∂28-Oct-87 0856 Common-Lisp-Object-System-mailer Re: Proof of CLOS Document
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 28 Oct 87 08:56:12 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Wed 28 Oct 87 08:52:37-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Wed, 28 Oct 87 08:55:27 PST
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 28 Oct 87 08:54:59 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 28 Oct 87 09:54:27 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Proof of CLOS Document
X-Mailer: mh6.5
In-Reply-To: Your message of Tue, 27 Oct 87 11:45:00 -0500.
<19871027164545.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 28 Oct 87 08:54:23 PST
Message-Id: <388.562438463@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
New page numbers refer to the draft on SAIL as of Oct. 22, which
may be out of date with the current draft, since I've not had
a chance to update.
> pg. 1-17: Last Paragraph. It is not clear from this what should happen
> if (TYPE-OF <obj>) returns a type speciifer which is a list. Should an
> error be signalled or should the CAR of the list be used? On pg. 42 of
> CLtL, the description of type specifiers which are lists suggests
> that the CAR should work.
> Is this the page that has figure 1-1 on it? I can't find anything on that
> page that looks like what you're referring to. I suspect you've uncovered
> a problem here, but I can't find the problem. Note however that the
> second paragraph on page 1-16, where it says (type-of I) is S if S is
> the proper name of C, else C, should say that this only applies when C
> is an instance of STANDARD-CLASS.
Yes, this is the page with Fig. 1-1. I think what I'm trying to anticipate
is implementation problems. Re-reading the second paragraph on page 1-16,
the specification seems to be clear on this. If TYPE-OF returns a list,
then it's up to the implementation to make sure the first element is
used in SYMBOL-CLASS.
> Overall: When referring to SETF functions, the list specifying a
> SETF function name is often not quoted. Example: (fboundp (setf <name>)).
> If the argument had been a function symbol name, however, it would have
> been quoted, since FBOUNDP is a function and therefore the arguments
> are evaluated. Shouldn't this be so for SETF function names as well,
> or is the assumption that (SETF <name>) is a macro which returns the
> actual name of the function (e.g. expands into something like '<actual na
me>)?
> It's just missing quote marks; no hairy macro like that was intended.
> Do you have page references for these typos? I think I noticed one or two,
> but they're easy to overlook and you probably saw some that I missed.
I marked some of them down. Here they are:
pg. 2-24, 4th paragraph; pg. 2-36, 4th paragraph; pg. 2-40 2nd bullet item;
pg 2-42, 1st paragraph under ARGUMENTS
> pg. 2-30: Top of page. I'm curious if the form generated is expected to
> be executable. That is, if <operator> can be a keyword symbol, then the
> implicit assumption is that the function cell of keywords can be
> bound. I know this is possible in Symbolics CL and not in ours, also
> I don't think CLtL says anything either way. Is there a Cleanup proposal
> on this?
> This moved to 2-29 in the latest draft (if things are getting shorter, that's
> a good sign!). I don't see anything that implies here that an implementation
> has to allow <operator> to be a keyword symbol. Certainly that was not
> intended. On the other hand, I don't know of anything in CLtL that allows
> implementations to forbid defining keyword symbols as functions. Anyway,
> the intent here is that <operator> is the name of a function, macro, or
> special form and can appear in the car of a form; precisely what objects
> satisfy that criterion is defined by CL rather than CLOS.
As mentioned, CLtL says nothing either way about whether keyword symbols
can be defined as functions. The only reason I asked about this was because
the last sentence in that paragraph states that <operator> can be specified
by a keyword option. If there are any other implementations besides ours
which have chosen to forbid binding the function cell of a keyword symbol
to a function, this might be a problem.
∂29-Oct-87 0918 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Oct 87 09:18:27 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae24364; 29 Oct 87 10:05 EST
Received: from csl.ti.com by RELAY.CS.NET id ah27125; 29 Oct 87 10:03 EST
Received: from Jenner by tilde id AA19194; Thu, 29 Oct 87 08:43:26 CST
Message-Id: <2771505853-154858@Jenner>
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Some open issues
In-Reply-To: Msg of Tue, 27 Oct 87 00:04 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Another open issue is that initargs you have to pass to make-instance
when making a standard-method. I think the best bet is that in addition
to the initargs already documented, you must pass :lambda-list, which
is a lambda-list from which the implementation is permitted to derive
the number of required and optional arguments, the presence of rest/key
arguments, the keyword names, for lambda-list congruence computation.
An implementation is also permitted to ignore the :lambda-list argument
and get this information from the :function argument, if in that
implementation a lambda-list can be retrieved from a function (CLtL
doesn't require that). I think the lambda-list can be anything that
meets these requirements, so it can be the specialized-lambda-list that
appears in the defmethod form, or it can be an ordinary function lambda
list, or it can be the type of stripped down lambda-list that can
be used with defgeneric. I think it's better for the derivation of
lambda-list congruence information from lambda-lists to be in the system,
rather than being reimplemented by every user, hence I suggest a lot
of freedom in what kind of lambda-list the initarg can accept. The
alternative would be to require the user to pass two numbers, a boolean,
and a list of keyword names, but I'd rather not do it that way.
That sounds good.
I have another related question. We said at the Palo Alto meeting (If I
remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct, the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
Patrick.
∂29-Oct-87 1109 Common-Lisp-Object-System-mailer comments on revised Chapter 1
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 11:09:01 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267210; Thu 29-Oct-87 13:04:01 EST
Date: Thu, 29 Oct 87 13:03 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on revised Chapter 1
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <19871029180349.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
page 1-14, 4th paragraph:
The sentence "Implementations may choose to invoke
update-instance-structure under other circumstances as well" isn't
really true. If the implementation decides to go through this process,
it always does both steps of the process, and it never just invokes
update-instance structure.
The other problem with that sentence is that it is buried in the middle
of the description of the two-step process itself.
The paragraph should begin by making it clear that we guarantee this
two-step process happens in one circumstance (set of local slots in an
instance changes), and it might happen in other circumstances, but we
aren't listing here all the times when an implementation would decide
to do this.
Here is a suggested rewriting of the beginning of the paragraph:
"If a class is redefined in such a way that the set of local slots
accessible in an instance of the class is changed, a two-step process of
updating the instance takes place. This two-step process can happen
in other circumstances, if the implementation finds it necessary. For
example, some implementations might need to trigger this two-step
process if the order of slots in storage is changed."
page 1-15: 3rd paragraph
Delete the sentence "Implementations may choose to invoke class-changed
under other circumstances as well." This isn't true for class-changed.
The first sentence states that the two-step process only happens under
certain circumstances. This isn't right. Perhaps the first step of
the process is only triggered under certain circumstances, but the
second step (calling class-changed) happens every time change-class is
called.
page 1-15:
We should state that changing the class of an instance never affects
shared slots.
page 1-17: Figure 1-1
The column entries under "Class precedence list" aren't right; they
exclude the class itself from its own precedence list. For example,
the CPL of array is (array t), not just (t). I also think the CPLs
here should be lists (with parentheses), to be consistent with the way
CPLs are presented in "Determining the Class Precedence List".
page 1-31:
Still don't have the standard method combination listed under built-in
method combination types.
page 1-41: third paragraph
There seem to be some spurious tildes (~) appearing in two of the forms.
∂29-Oct-87 1259 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 12:59:08 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267493; Thu 29-Oct-87 15:59:51 EST
Date: Thu, 29 Oct 87 15:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Some open issues
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2771505853-154858@Jenner>
Message-ID: <19871029205951.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
We said at the Palo Alto meeting (If I remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct,
It is.
the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
It has to be during the macro expansion of defmethod, since the :function
initarg to standard-method (although I don't have any documentation that
says this explicitly) can be a function that has already been compiled
and can't have its lambda-list mucked with.
The documentation on 2-53, 2-54 of how to create generic functions and
methods of your own is pretty unsatisfactory. It seems like a bit too
much detail to be covering under make-instance, yet it's not really
enough detail to cover all of the issues, like what does the lambda-list
of the :function have to look like? And what about making ones own
classes? I think this stuff may have to move into chapter 3 and become
documentation sections of their own for classes standard-method,
standard-class, and standard-generic-function, rather than being
tucked inside make-instance.
∂29-Oct-87 2147 Common-Lisp-Object-System-mailer standard type class
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Oct 87 21:47:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 267958; Fri 30-Oct-87 00:48:26 EST
Date: Fri, 30 Oct 87 00:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: standard type class
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871030054823.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
This is a first draft.
The problems with the term "standard type class" are:
- the name is too close to "standard class" so it's easy to get confused.
- the semantics are too ill-defined. When we say "could be extended"
to allow subclassing and make-instance, this sounds like it refers to
standard type classes in general, but what it actually means is that
an individual class documented as a standard type class could be
implemented as a standard class.
- we haven't made clear enough that an object has standard-type-class
as -a- metaclass, but -the- metaclass is implementation-dependent
Suggestion:
- eliminate the term "standard type class"
- when we mean "a class that corresponds to a predefined Common
Lisp type" we should say exactly that, no need to abbreviate.
- rename the standard-type-class metaclass to built-in-class,
and clarify that it is implementation-dependent whether any
potentially built-in class is in fact built-in and has this
metaclass.
- clarify the requirements on portable programs
These are all the uses of the phrase "standard type class" (with or
without hyphens) that appear in the documentation as of a couple
days ago:
1-16 -- see rewrite below
1-34 -- see rewrite below
2-11 2nd remarks para -- delete the second sentence. We don't need
a "for example" and don't need to say anything more than that change-class
is only guaranteed to work for standard classes.
2-22 1st remarks para -- delete the third sentence. The section
"Redefining Classes" already covered the rules here.
2-54 last remarks para -- delete, this has already been covered and
doesn't need to be repeated.
2-79 1st args para last sentence -- this doesn't belong here, delete it.
Perhaps slot-value should say that it signals an error if given an
instance of a built-in class (I don't think it calls slot-missing
in that case.)
On page 1-16, the rest of the section after the first three paragraphs
is replaced by the following (edited from the TEX source on SAIL):
Many but not all of the predefined Common Lisp type specifiers have a
corresponding class with the same proper name as the type. For example,
the type {\bf array} has a corresponding class named {\bf array}. No
type specifier that is a list, such as {\tt (vector double-float 100)},
has a corresponding class. No type defined by {\bf deftype} has a
corresponding class.
Each class that corresponds to a predefined Common Lisp type specifier
can be implemented in one of three ways, at the discretion of each
implementation. It can be a {\bit standard class\/}, of the kind
defined by {\bf defclass}, a {\bit structure class\/}, defined
by {\bf defstruct}, or a {\bit built-in class\/}, implemented in
a special, non-extensible way. For example, most Common Lisp
implementations reserve a particular bit pattern for representing
conses. In such an implementation, {\bf cons} is a built-in class.
Built-in classes have restricted capabilities, because of their special
representation. Attempting to use {\bf defclass} to add new subclasses
to a built-in class signals an error. Calling {\bf make-instance} to
create an instance of a built-in class signals an error. Many built-in
classes do not have slots and calling {\bf slot-value} signals an error.
Redefining a built-in class or using {\bf change-class} to change the
class of an instance to or from a built-in class signals an error.
However, built-in classes {\it can\/} be used as parameter specializers
in methods.
A portable program must assume that all classes that correspond to
predefined Common Lisp type specifiers are built-in classes. In a
particular implementation one of these classes might be a standard
class, but in other implementations it could be a built-in class.
Thus a portable program may not define a subclass, make an instance,
reference a slot, redefine, or change-class a potentially built-in class.
It is possible to distinguish standard from built-in classes by checking
the metaclass. A standard class is an instance of {\bf standard-class}
or of a subclass of it. A built-in class is an instance of
{\bf built-in-class} or of a subclass of it. Note that the metaclass
of a class that corresponds to a predefined Common Lisp type specifier
is implementation-dependent.
Each structure type created by {\bf defstruct} without using the
{\bf :type} option has a corresponding class. This class is an
instance of {\bf structure-class}. A portable program must assume
that {\bf structure-class} is a subclass of {\bf built-in-class}
and suffers the same restrictions. Whether {\bf structure-class}
in fact is a subclass of {\bf built-in-class} is implementation-dependent.
The {\bf :include} option of {\bf defstruct} creates a direct subclass
of the class that corresponds to the included structure.
The purpose of specifying that many of the standard Common Lisp types
have a corresponding class is to allow users to write methods that
discriminate on these types.
Method selection requires that a class precedence list can be
determined for each class. This list orders the class and its superclasses
from most to least specific.
The hierarchical relationships among
the Common Lisp types are maintained by the classes corresponding to
those types. Thus the existing type hierarchy is used for determining
the class precedence lists for each class that corresponds to
a predefined Common Lisp type.
In some cases, {\it Common Lisp: The
Language\/} does not specify a subtype/supertype relationship for two
supertypes of a given type. For example, {\bf null} is a subtype of
both {\bf symbol} and {\bf list}, but {\it Common Lisp: The Language\/}
does not specify whether {\bf symbol} is more or less specific than {\bf
list}. The \CLOS\ specification defines those relationships for all
such classes.
The following table lists the set of classes that correspond to
predefined Common Lisp types required by
\CLOS. The superclasses of each such class are presented in
order from most specific to most general, according to the class precedence
list for the class.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil\hfil\tabskip \dimen0 plus .5 fil&\hfil\cr %was &
\noalign{\vskip -9pt}
\hfil\bf Class&\bf Class Precedence List\span\omit\span\omit\cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
array&t\cr
bit-vector&vector, array, sequence, t\cr
character&t\cr
complex&number, t\cr
cons&list, sequence, t\cr
float&number, t\cr
integer&rational, number, t\cr
list&sequence, t \cr
null&symbol, list, sequence, t\cr
number&t\cr
ratio&rational, number, t\cr
rational&number, t\cr
sequence&t\cr
string&vector, array, sequence, t\cr
symbol&t\cr
t\cr
vector&array, sequence, t\cr
\noalign{\vskip -9pt}
}}
\caption{}
\endfig
Individual implementations can allow other type specifiers to have a
corresponding class. Individual implementations can also add additional
subclass relationships and can add additional elements to the class
precedence lists in the above table,
as long as they do not violate the type
relationships and disjointness requirements
specified by {\it Common Lisp: The Language\/}.
However, individual implementations are not free to add subclass
relationships involving user-defined standard classes.
This subsection on page 1-34 is replaced as follows:
\beginsubSection{Standard Metaclasses}
The \CLOS\ provides a number of predefined metaclasses. These
include the following: {\bf standard-class},
{\bf built-in-class}, and {\bf structure-class}.
% funcallable-class?
\beginlist
\item{\bull}
The class {\bf standard-class} is the default class of classes defined
by {\bf defclass}.
\item{\bull} The class {\bf built-in-class} is the class of classes
that have special implementations with restricted capabilities.
All classes that correspond to the standard Common Lisp types
specified in {\it Common Lisp: The Language\/} by Guy L. Steele Jr.
are potentially instances of {\bf built-in-class} or a subclass
of {\bf built-in-class}.
%These types are listed in Figure~1-1.
It is implementation-dependent whether each of these classes
is actually built-in.
\item{\bull}
All classes defined by means of {\bf defstruct} are instances of
{\bf structure-class} or a subclass of {\bf structure-class}.
The class {\bf structure-class} is potentially a subclass
of {\bf built-in-class}.
\endlist
\endsubSection%{Standard Metaclasses}
∂30-Oct-87 0809 Common-Lisp-Object-System-mailer Re: standard type class
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 30 Oct 87 08:09:46 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Fri 30 Oct 87 08:06:14-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Fri, 30 Oct 87 08:07:23 PST
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 30 Oct 87 08:07:06 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 30 Oct 87 09:06:40 pst
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: standard type class
X-Mailer: mh6.5
In-Reply-To: Your message of Fri, 30 Oct 87 00:48:00 -0500.
<19871030054823.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 30 Oct 87 08:06:37 PST
Message-Id: <3610.562608397@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> Suggestion:
> - eliminate the term "standard type class"
> - when we mean "a class that corresponds to a predefined Common
> Lisp type" we should say exactly that, no need to abbreviate.
> - rename the standard-type-class metaclass to built-in-class,
> and clarify that it is implementation-dependent whether any
> potentially built-in class is in fact built-in and has this
> metaclass.
> - clarify the requirements on portable programs
These suggestions and the accompanying draft appear to clarify the built
in class section.
jak
∂30-Oct-87 0858 Common-Lisp-Object-System-mailer Re: Some open issues
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 30 Oct 87 08:58:04 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad09175; 30 Oct 87 9:35 EST
Received: from csl.ti.com by RELAY.CS.NET id ag03690; 30 Oct 87 9:32 EST
Received: from Jenner by tilde id AA15111; Fri, 30 Oct 87 07:32:41 CST
Message-Id: <2771588021-5091608@Jenner>
Date: Fri, 30 Oct 87 07:33:41 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Some open issues
In-Reply-To: Msg of Thu, 29 Oct 87 15:59 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
Date: Thu, 29 Oct 87 15:59 EST
From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
Subject: Re: Some open issues
Date: Thu, 29 Oct 87 08:44:13 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
We said at the Palo Alto meeting (If I remember correctly) that something like
(defmethod foo ((a c1) (b c2) &key x )
...)
would result into a method which lambda list is ((a c1) (b c2) &key x)
(used for the lambda-list congruence computation),
and a function which lambda list can be (a b &key x &allow-other-keys).
It is done so because the generic function check the keywords arguments,
not the method.
If what I said is correct,
It is.
the question is: When do we change/generate the
function's lambda list? Do we generate the final one during the
macroexpansion of DEFMETHOD or do we change the lambda-list during the
execution of (make-instance 'standard-method ...)?
It has to be during the macro expansion of defmethod, since the :function
initarg to standard-method (although I don't have any documentation that
says this explicitly) can be a function that has already been compiled
and can't have its lambda-list mucked with.
I had the same opinion on this.
The documentation on 2-53, 2-54 of how to create generic functions and
methods of your own is pretty unsatisfactory. It seems like a bit too
much detail to be covering under make-instance, yet it's not really
enough detail to cover all of the issues, like what does the lambda-list
of the :function have to look like? And what about making ones own
classes? I think this stuff may have to move into chapter 3 and become
documentation sections of their own for classes standard-method,
standard-class, and standard-generic-function, rather than being
tucked inside make-instance.
I agree.
∂30-Oct-87 1422 Common-Lisp-Object-System-mailer comments on portions of the Oct 26 10:05 draft
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 30 Oct 87 14:22:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 268751; Fri 30-Oct-87 17:23:14 EST
Date: Fri, 30 Oct 87 17:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: comments on portions of the Oct 26 10:05 draft
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871030222257.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
In general the document is greatly improved and I'm fairly happy with it,
execpt for these last few points.
I've excluded comments on things that appeared to be already fixed in the
TEX source, since I was reading an unproofread draft. Also I tried to
avoid duplications others' comments.
1-10: "A subclass inherits methods in the sense that any method applicable to
an instance of a class is also applicable to instances of any subclass
of that class (all other arguments to the method being the same)."
At the beginning of the second line, should "an instance" be "all instances"
so as to avoid any questions about methods-on-individuals?
1-17: "Note that instances of standard-type classes are disjoint with all other
types."
This is wrong, type disjointness of standard-type classes is controlled
by CLtL, not by us. The previous draft said "Note that instances of
standard classes are type disjoint with all other types" and I think the
switch from standard classes to standard-type classes was an editing
error. In the "built-in-class" stuff I mailed out last night, I
included a suggested rewrite that more explicitly conveys the idea that
I think this paragraph was hinting at.
1-19 top of page: the explanation of looping precedence order is too complicated,
I don't think we really need double indices here. Can't we just say
C1 through Cn, n>=2, where each precedes the next and also Cn precedes C1?
I think trying to call Cn C2 was what complicated the notation.
1-19 last paragraph before examples: I still think this should be generalized
to cover relatively separated subgraphs whose common element is not T, as
I said in earlier comments.
1-23 2nd para:
"When a new {\bf defgeneric} form is evaluated and a generic
function of the given name already exists, the existing generic function
object is modified. This does not modify any of the methods associated
with the generic function."
except for modifications as a result of :method options in the defgeneric.
1-23 2nd bullet: "The lambda-list of the new method
must be congruent with the lambda-list of the generic function or else
an error is signaled." applies to both new and redefined methods, i.e. both
bullets, so this should not be inside the second bullet. It looks like
it and the cross-referenced to congruence should be a separate paragraph
immediately after the bullets, preceding the paragraph about what happens
when no generic function by that name already exists.
1-24: "...parameter specializers
are used in the functional interface to method creation ({\bf
make-instance} of {\bf standard-method} and {\bf get-method})." would
be more legible if it said: "...parameter specializers
are used in the functional interface to method creation ({\bf get-method}
and {\bf make-instance} of {\bf standard-method})."
1-25 first paragraph: "By convention, qualifiers are usually
symbols, but it is possible to use a vector used as a qualifier."
delete "used"
1-25 second paragraph: "When a method combination type is
defined using the short form of {\bf define-method-combination},
primary methods are defined to include not only the methods qualified
with the name of the type of method combination, but certain others as
well." Delete "not only" and "but certain others as well". The only
primary methods are the qualified ones. Add that auxiliary methods
for this case are :around methods.
1-41: the term "setf macro" is used without being defined. Adding
", defined by defsetf or define-setf-method," should be sufficient to
give the reader the idea of what we mean by "setf macro."
We might want to be a little more explicit, rather than just relying
on the example in the last bullet, about the fact that the new-value
is received by the setf function as its first argument. Also to avoid
any wondering, we could say that in a setf generic function this argument
is just as specializable as any other required argument.
∂02-Nov-87 1330 Common-Lisp-Object-System-mailer :accessor slot option
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Nov 87 13:29:52 PST
Received: from Semillon.ms by ArpaGateway.ms ; 02 NOV 87 13:30:42 PST
Date: Mon, 2 Nov 87 13:30 PST
From: Gregor.pa@Xerox.COM
Subject: :accessor slot option
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <871102133014.0.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I have become uncomfortable with the :reader and :accessor slot options.
Right now, at the very least, I would like to add a :writer option, I
may also want to remove or rename the :accessor option. The :writer
option would work in the obvious way:
(defclass foo ()
((a :reader foo-a
:writer (setf foo-a))))
This would allow someone who wanted to define a writer but no reader to
do it, it also makes the mapping onto the new setf proposal more
explicit.
I agree that in cases where you want both a reader and a writer its
probably too verbose, so we probably need to keep the :accessor option,
but what if we renamed it, maybe to :reader-writer or perhaps
:accessors.
Or it may just be that re-reading that part of the spec will make me
happy.
-------
∂02-Nov-87 1417 Common-Lisp-Object-System-mailer Comments on chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Nov 87 14:17:28 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 270177; Mon 2-Nov-87 17:18:28 EST
Date: Mon, 2 Nov 87 17:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comments on chapter 2
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <19871102221820.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Page numbers are from the Oct 26 10:17 draft, but I've omitted comments
on things that are already fixed in the source in the latest version on SAIL.
2-10: Cross-reference to ``Changing Classes'', which has been renamed.
Example hasn't been updated yet to realize that rho is the radius and
theta is the angle.
2-11: First remarks paragraph: this could just speak of classes whose
metaclass is standard-class, without worrying about whether or not the
:metaclass option was specified, similar to the way some similar text
was fixed up in chapter 1 recently. Not edited for standard-type-class
removal yet. The phrase "After completing all other actions, {\bf
change-class} invokes the generic function {\bf class-changed}." is
somewhat unclear as to what "all other actions" are, maybe some text got
lost here. This should be improved when the business of who evaluates
the :initforms is straightened out.
2-12: Cross reference to ``Redefining Classes'' should be to
``Changing the Class of an Instance''.
2-14: Cross reference to ``Changing Classes'' should be to
``Changing the Class of an Instance''.
2-39: missing quote mark in (documentation (setf symbol) 'function).
I forget if this one was already commented upon.
2-54: under make-instance, we have
"The {\bf :function} argument is the method function.
The length of the list of specializers must be equal to
the number of required arguments of the method function, or
else an error is signaled."
Since Common Lisp doesn't require implementations to be able to
determine the number of required arguments of a function, given the
function, I don't see how this requirement to signal an error
can be implemented. We might have to make this the same less stringent
error checking that CLtL prescribes for calling a function with the
wrong number of arguments.
Also as mentioned before this section will need to discuss more about
the relations between the method lambda-list and the method function
lambda-list.
2-55: The first Purpose ("Purposes"?) sentence for make-instances-obsolete
is misleading. Not every defclass redefinition calls this, it's only
guaranteed to be called under the circumstances described on 1-13.
Also there is a conflict between the value of make-instances-obsolete
being eq to the class argument, and the class argument being allowed
to be a name of a symbol; just needs the wording cleaned up a little.
Also I'm not sure what the remark
"The generic function {\bf make-instances-obsolete} is invoked only on
classes that are instances of {\bf standard-class}."
means; does this mean the user is not allowed to invoke it on other
classes, or is this more of the statement under Purpose of when defclass
invokes this?
2-70: I think we ought to mention that the typical implementation will
compile slot-value inline, or somehow efficiently, in methods. Users need
to have some rough idea of what sort of efficiency to expect, and reading
the document the way it is right now would tend to lead the naive reader
to think that CLOS slots are much less efficient to access than defstruct
slots, whereas the intention has clearly been that there be only a minor
efficiency cost for using CLOS slots, at least in the majority of
implementations. We don't have to give the details (except maybe in the
meta-object chapter), but we ought to mention the possibility of optimization.
2-72: In the first remarks paragraph for symbol-macrolet, "expansion"
is probably supposed to be in italics. At least, I think what is intended
here is to say that the scope does not include the -expansion- forms
that are substituted for the -symbols-. At first I thought "expansion"
referred to the result of expanding the invocation of symbol-macrolet.
2-73: First sentence for update-instance-structure is missing "be".
Also this hasn't been updated yet to reflect the division of labor between
caller and primary method that has been adopted in chapter 1.
2-77: The remarks for with-added-methods still speak of modifying an existing
generic function. This needs to be rephrased in terms of defaulting the
values of these options, for the newly-created generic function, from their
values in the existing generic function.
2-79: "The macro {\bf with-slots} can be used inside a method or inside
any function." implies it can't be used at top level, but that's not what
we mean to say.
∂03-Nov-87 0801 Common-Lisp-Object-System-mailer Comment on the chapter 2.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 3 Nov 87 08:01:45 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae02430; 3 Nov 87 10:36 EST
Received: from csl.ti.com by RELAY.CS.NET id af06989; 3 Nov 87 10:32 EST
Received: from dsg by tilde id AA24093; Tue, 3 Nov 87 08:36:00 CST
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 3 Nov 87 08:01:35 CST
Message-Id: <2771935258-3166612@Jenner>
Date: Tue, 3 Nov 87 08:00:58 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Comment on the chapter 2.
In the Oct 26 draft, page 2-65(slot-boundp), 2-67(slot-makunbound),
2-70(slot-value), in the remarks field, the call to SLOT-MISSING is
incorrect. INSTANCE must be added after (CLASS-OF INSTANCE).
Patrick.
∂03-Nov-87 1045 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Nov 87 10:45:09 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 03 NOV 87 10:37:34 PST
Date: 3 Nov 87 10:29 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Comment on the chapter 2, Version of Nov 2.
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <871103-103734-2963@Xerox>
General Comment: Much improved again. Having method signatures makes a
big difference. I think that if there is a method signature, there
should not be a section called Syntax. They are to some extent
redundant, and where they are not, Syntax was almost always wrong.
2-8 This is the first example of the redundancy. Please take out
Syntax, and the first two sentences under Arguments. The signature
specifies what the types of the arguments must be, and if people add
another method the arguments need not be those objects.
For example, suppose someone wanted to add a method:
add-method (s symbol) (lambda-exp listp)
where s was supposed to name a generic function and lambda-exp was a
list for a function, then the statements under arguments would be
untrue.
2-9 Last sentence of third paragraph "It defines the next method ... "
--> "The standard method combination type defines the next method ... "
(I garden pathed on the "It")
2-11 The environment argument is only mentioned. There is no statement
here, or later for symbol-class, etc about what it means to have the
environment. So for example,
"(cboundp 'foo e1) returns true if foo is bound to a class IN THE
ENVIRONMENT DENOTED BY e1."
2-12 Second paragraph, first sentence should read
"If in the old class there is ANY slot of the same name as any LOCAL
slot in the new class, the value of that slot is unchanged"
Remove Syntax section, Remove first two lines of Arguments. The last
sentence should read
"... and then invokes the first method with the class returned as value
from (symbol-class symbol)."
In Remarks section, you can put the comment (if you want) about possible
extensions to objects that are not standard class. But I would just
leave it out as redundant with the introductory statement about
generic-functions being extendable.
Examples: you need an :initarg :x and :initarg :y in the defclass to
have the make-instance work on the next page.
2-13 Remarks: Second sentence "... can be used to assign values to slots
in the transformed instance."
Next paragraph: Third sentence might read better as
"The methods currently executing may no longer be applicable."
The complication of combined methods is not worth the confusion here, I
think.
2-17 Purpose: Try "... and returns a symbol. This symbol is not
guaranteed to be the name of this class. See remarks below."
Remove Syntax.
Remarks: It is possible that C /= (symbol-class(class-name C)). For
example:
(defclass foo () (a))
(defclass bar () (b))
(setq f1 (symbol-class foo))
(setq f2 (symbol-class bar))
(setf (symbol-class foo) f2)
(class-name f1) --> foo
(class-name (symbol-class 'foo)) --> bar
2-19 Purpose: "... name a class IN AN ENVIRONMENT".
Remarks: It sounds like the symbol is somehow spoiled (" the symbol is
no longer usable as the name of a type"). Why not say something like
"the symbol is no longer associated with a class that defines a type."
2-21 syntax
replace {slot-option}* by [[↑ slot-option]]
and use
{:accessor generic-function-name}*
{:reader generic-function-name}*
{:initarg name}*
as the last three items of slot-option. Then the remarks on which
options can appear more than once in Arguments are redundant.
2-22 First paragraph. "... the definition of that class is replaced FOR
INSTANCES OF STANDARD-CLASS."
2-23 para 2 "... is not allowed as an abbreviation for the syntax
(slotname :initform). THIS IS DIFFERENT THAN DEFSTRUCT."
2-24 First sentence, same as for p 2-22 " ... class is guaranteeed to be
redefined for classes that are instances of standard-class."
2-26
The syntax of defgeneric now shows a lambda-list as a required argument.
I thought :lambda-list was supposed to be a keyword argument. Similarly
for generic-labels, generic-flet, generic-function, and
with-added-methods. When there are method descriptions provided, the
lambda-list is often redundant, and hence can be a cause for mistakes.
My notes from the meeting show that there was no required lambda-list,
at least for the generic-labels, generic-flet, generic-function, and
with-added-methods. Hence by extension, there should not be a required
lambda-list in defgeneric.
2-27 "The :argument-precedence-order option has a value which is a
permutation of the list of required arguments for generic function. It
is used to specify the order in which the required arguments ... When
the :argument-precedence-order is given, then an explicit lambda-list
for the generic function must be given. ..."
Example:
(defgeneric char-to-stream
(:lambda-list (char stream &optional font))
(:argument-precedence-order (stream char)))
Is this the correct syntax, or should it be:
(defgeneric char-to-stream
(:lambda-list char stream &optional font)
(:argument-precedence-order stream char))
I don't like this as well.
2-40
Remove Syntax for describe
2-41
Remove Syntax for documentation (Here it specifies that the second
argument is optional and we cannot specialize on optional arguments).
If Common Lisp has it as optional, then the signatures must only be on
the first type, with constraints specified in English on the optional
argument.
2-43
Purpose: Remove second sentence , that is "If name does not specify a
generic function, an error is signalled."
2-44
"The keyword arguments correspond to the option arguments of defgeneric,
except that the :method-class and the :generic-function-class can be
class objects as well as names."
2-45, 2-47, 2-49 Remark about required lambda-list again.
2-55
This description of make-instance is just wrong. The signatures are
wrong (they are off a metalevel). They would be appropriate signatures
for initialize-instance It should say something like
Method Signatures:
make-instance (class standard-class) &key &rest initargs
Arguments:
The initargs arguments are explicitly checked within make-instance by
the generic function check-initargs. These initargs are the union of
the keyword arguments allowed for all applicable methods on
initialize-instance, and the :initarg options of the class.
See the section on Object Creation. For instances of particular
classes, see the description of the initialize-instance method.
---
Then if we want we can put in the remarks section on initialize-instance
the arguments that each of the initialize-instance methods take.
[[However, I would prefer to see these in Chapter 3 under the
descriptions of the classes]]
initialize-instance (class standard-class) &key :direct-superclasses
:direct-slots :options
The :direct-superclasses argument is a list of symbols (class names) or
class objects. The :direct-slots argument is a list of slot-description
objects (see chapter 3) and the :options is a list of the type accepted
by defclass as class options, except :metaclass is not allowed.
initialize-instance (gfn standard-generic-function) &key :lambda-list
...
initialize-instance (method standard-method) &key ...
2-58 Purpose (Why is this one plural?)
"... when defclass has been used to redefine an existing class WITH
METACLASS standard-class."
Remove Syntax
Arguments: The class argument is a class object whose instances are to
be made obsolete.
2-59
Next to last paragraph. "... the result is a form that calls the first
method, M1, and arranges for call-next-method to reach the next method,
M2, in the list. An invocation of call-next-method in M2 reaches the
following method, M3, and this continues through the methods in the
order they appear in method-list. If a call-next-method is invoked by
the last method in method-list, an error is signaled."
2-64
Remove Syntax. Remove comment in purpose about method on
standard-generic-function signals an error (It appears 6 lines below)
2-67 Remove syntax. Remove first two sentences of Arguments.
2-74
Again something needs to be said about relationship of name and
environment.
2-80
It needs to be said that if name is bound to a macro, then an error is
signalled.
2-82
There are quote marks that are missing around slot-entry in all calls to
slot-value.
e.g. (slot-value #:Temp 'slot-entry1)
∂03-Nov-87 1354 Common-Lisp-Object-System-mailer CLOS mailing list
Received: from UUNET.UU.NET by SAIL.STANFORD.EDU with TCP; 3 Nov 87 13:54:48 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA08285; Tue, 3 Nov 87 16:55:32 EST
From: mcvax!crin.crin.fr!masini@uunet.UU.NET
Received: by mcvax.cwi.nl; Tue, 3 Nov 87 22:35:56 +0100 (MET)
Received: by inria.inria.fr; Tue, 3 Nov 87 16:21:56 +0100 (MET)
Date: Tue, 3 Nov 87 16:04:18 +0200
Received: by crin.crin.fr, Tue, 3 Nov 87 16:04:18 +0200
Subject: CLOS mailing list
To: Common-Lisp-Object-System@sail.stanford.edu
Message-Id: <562946603/masini@crin.crin.fr>
We are currently making a study about Object Oriented Languages, their past,
present and future.
I've been told you were mailing news about the conception and the evolution of
CLOS. Is it possible for me to be added to your mailing list ?
Thanks in any case.
Gerald MASINI, CRIN (Centre de Recherche en Informatique de Nancy)
email: masini@crin.crin.fr
post: CRIN B.P. 239 54506 Vandoeuvre-les-Nancy Cedex FRANCE
phone: +33 83.91.21.45
∂03-Nov-87 1447 Common-Lisp-Object-System-mailer CLOS mailing list
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Nov 87 14:47:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 271163; Tue 3-Nov-87 17:48:12 EST
Date: Tue, 3 Nov 87 17:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CLOS mailing list
To: mcvax!crin.crin.fr!masini@uunet.UU.NET, masini@crin.crin.fr
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <562946603/masini@crin.crin.fr>
Message-ID: <19871103224748.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 3 Nov 87 16:04:18 +0200
From: mcvax!crin.crin.fr!masini@uunet.UU.NET
We are currently making a study about Object Oriented Languages, their past,
present and future.
I've been told you were mailing news about the conception and the evolution of
CLOS. Is it possible for me to be added to your mailing list ?
This mailing list is a working group developing a specification for a proposed
new object-oriented addition to Common Lisp. It's not really a news group.
There is heavy traffic with a great amount of detail, so I suspect this isn't
really the list you want to be on.
∂03-Nov-87 1512 Common-Lisp-Object-System-mailer Comment on the chapter 2, Version of Nov 2.
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Nov 87 15:12:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 271203; Tue 3-Nov-87 18:13:30 EST
Date: Tue, 3 Nov 87 18:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Comment on the chapter 2, Version of Nov 2.
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871103-103734-2963@Xerox>
Message-ID: <19871103231327.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 3 Nov 87 10:29 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
2-21 syntax
replace {slot-option}* by [[↑ slot-option]]
and use
{:accessor generic-function-name}*
{:reader generic-function-name}*
{:initarg name}*
as the last three items of slot-option. Then the remarks on which
options can appear more than once in Arguments are redundant.
Stylistic comment: I hope we are not changing the style so that it is
impossible for a reader who skips over the BNF syntax notation to
understand the document. I think that would be most unfortunate. I'd
much rather have a little redundancy than make it necessary to
understand the fine points of this increasingly obscure notation in
order to understand the document.
2-26
The syntax of defgeneric now shows a lambda-list as a required argument.
I thought :lambda-list was supposed to be a keyword argument. Similarly
for generic-labels, generic-flet, generic-function, and
with-added-methods. When there are method descriptions provided, the
lambda-list is often redundant, and hence can be a cause for mistakes.
My notes from the meeting show that there was no required lambda-list,
at least for the generic-labels, generic-flet, generic-function, and
with-added-methods. Hence by extension, there should not be a required
lambda-list in defgeneric.
I don't think we agreed in the meeting to remove these lambda-lists. My
copies of the draft documents from the meeting show the lambda-list (along
with a bunch of other stuff) missing in the first version of some writeups,
but present in the second version that we produced after discussion and
rationalization of the syntax of all the things having to do with generic
functions. Perhaps you got mixed up on which version was newer? There are
no dates on these pages but at the meeting I wrote "old" or something
on the older ones.
More comments later, perhaps.
∂04-Nov-87 1018 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
This message is about the format for description of generic functions
in chapter 2. The points are made as a response to a message that Danny
sent, but no one should interpret this as picking on his comments, which
simply serve to bring some decisions to light.
Danny writes:
``I think that if there is a method signature, there
should not be a section called Syntax. They are to some extent
redundant, and where they are not, Syntax was almost always wrong.''
Hm. I should have written the class redefinition section `wrong', then we
could have eliminated that too. Renaming ``Syntax'' to ``Generic Function
Syntax'' is useful when the generic function lambda-list is important to
know - that is, when it doesn't derive from the method lambda-lists.
Think of INITIALIZE-INSTANCE. And maybe it's generally useful for people
who are populating their CLOS with additional methods.
``<Add-method> This is the first example of the redundancy. Please take out
Syntax, and the first two sentences under Arguments....''
If I do that, here's the result:
******************************************************************************
Method Signatures:
add-method (generic-function standard-generic-function) (method standard-method)
Arguments:
The lambda-list of the method function must be congruent with the
lambda-lists of all other methods associated with the generic function and
with the lambda-list of the generic function, or else an error is
signaled.
******************************************************************************
Unfortunately, there is no method function mentioned. There is a larger
liklihood that this would mean the method function of the argument passed
to {\it method}, I suppose. A rewording of this could be:
``The lambda-list of the method function of the method object passed as
{\it method} must be congruent with the lambda-lists of all other methods
associated with the generic function and with the lambda-list of the
generic function, or else an error is signaled.''
One reason to describe the arguments in English is to introduce some
simple noun phrase to use to talk about these arguments.
Danny goes on:
``The signature specifies what the types of the arguments must be, and if
people add another method the arguments need not be those objects.''
This brings up the interesting point. We have a heading called ``Purpose:''.
Linda and I spent several hours last night trying to redesign the generic
function pages, and the question of when the purpose should be written as
the purpose of the generic function and when it should be the purpose
of some method. Here is an example, again ADD-METHOD.
****************************************************************************
Purpose:
The generic function add-method adds a method to a generic function. It
destructively modifies the generic function and returns the modified
generic function as its result.
****************************************************************************
ADD-METHOD has 1 method defined. This purpose could be moved to
describe the purpose of that method. If we do that, then any additional
methods are not constrained to have any particular behavior or purpose.
For instance, ADD-METHOD when applied to 2 matrices could add them - it
is the add method, after all.
The purpose when left as a description of the generic function requires
implementors to define only methods for ADD-METHOD that satisfy that
purpose.
The spirit of object-oriented programming, I guess, states that users can
define whatever the hell they like for methods. The spirit of reasonable
abstraction states that users should be required to choose their own
random names for their random methods, leaving ADD-METHOD for methods that
add methods to generic functions.
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Danny writes about CHANGE-CLASS:
``Remove Syntax section, Remove first two lines of Arguments. The last
sentence should read "... and then invokes the first method with the class
returned as value from (symbol-class symbol)."''
The last sentence cannot say this unless you are imagining that the
two methods on CHANGE-CLASS are defined as follows: Use LABELS to make
two functions, one that assumes a class as its second argument and one
that assumes a symbol as its second argument. Have the second invoke
the first (as a function) with (symbol-class symbol) as its second argument.
Now take these two functions and make method objects out of them with the
usual paraphenalia and stuff them into CHANGE-CLASS using ADD-METHOD.
I don't think this is what we mean. Therefore the purpose of the
second method must say something like:
``This method invokes CHANGE-CLASS on {\it instance} and (symbol-class
{\it symbol}).''
This is particularly relevant when the spirit of object-oriented programming
encourages us to write random methods for CHANGE-CLASS, and we certainly
want those methods to get a second crack at the instance in this case.
This brings up the second general point, which is are we going to require
that a pristine CLOS have all and only the methods described in the
specification? Danny's proposed rewrite of the description of CHANGE-CLASS
implies he believes so. I tend to favor the restriction.
Currently there is a statement in the introduction to Chapter 2 that
states:
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
Opinions?
-rpg-
∂04-Nov-87 1025 Common-Lisp-Object-System-mailer Lambda-list in Defgeneric
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
In my notes I have the typeset version of the description of
DEFGENERIC that we discussed at the Palo Alto meeting, and there are
inked-in changes on it. The changes moved things around, but left
the lambda-list as required. I also have the hand-written notes that
Sonya, I think, took during the discussion before I produced the typeset
version and from which the typeset version was derived, and it
has the lambda-list as required.
-rpg-
∂04-Nov-87 1104 Common-Lisp-Object-System-mailer Issues raised by comments on chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 11:04:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 04 NOV 87 10:59:02 PST
Date: Wed, 4 Nov 87 10:58 PST
From: Gregor.pa@Xerox.COM
Subject: Issues raised by comments on chapter 2
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: common-lisp-object-system@SAIL.Stanford.EDU
In-Reply-To: The message of 4 Nov 87 10:18 PST from Dick Gabriel
<RPG@SAIL.Stanford.EDU>
Message-ID: <871104105832.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: 04 Nov 87 10:18 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
.
.
The spirit of object-oriented programming, I guess, states that users can
define whatever the hell they like for methods. The spirit of reasonable
abstraction states that users should be required to choose their own
random names for their random methods, leaving ADD-METHOD for methods that
add methods to generic functions.
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Whenever 'reasonable' is more like it. For example, the purpose of the
add-method generic function is to add a method to a generic function.
If there is already a similar method an error is signalled. The generic
function is completely updated to know about the new method.
The particular method on (standard-gf standard-method), has some of its
own private behavior as well. For example, it defines what it means for
methods to be similar in this case (same qualifiers and specializers).
It also defines what the lambda-list congruence rules will be.
So its not a matter of whenever feasible, its a matter of reasoning it
out on a case by case basis.
.
.
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
I think this should be changed so that we can make this statement about
some generic functions and not others. Even in the cases where we say
its OK to have more methods we are going to want some language for
placing some restrictions on where there could be methods. For example,
in print-object, an implementation should be free to have methods on as
many of its pre-defined classes as it likes, but it should not be
allowed to define print-object methods on user-defined classes behind
said user's back.
Of course what is really causing all the problem here is that none of us
has any real idea what a 'protocol' is or how to specify one.
-------
∂04-Nov-87 1210 Common-Lisp-Object-System-mailer method signatures
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Nov 87 12:09:55 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272050; Wed 4-Nov-87 15:10:51 EST
Date: Wed, 4 Nov 87 15:10 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: method signatures
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <19871104201026.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
I like the new method signatures. They give good information in a
concise format. However, I don't believe that a Method Signature is
redundant with Syntax.
When readers look in the specification for a generic function such as
ADD-METHOD, there are two different kinds of information they might be
seeking:
How do I call this g-f?
--Answered by Syntax
What methods are guaranteed to exist for this g-f?
--Answered by Method Signature
Yes, I know that the reader can divine the answer to the first question
by looking at the Method Signature. But it takes a little bit of
parsing with your eyes, and I think we should spare our readers from
that.
Actually, the more I think about this, the more strongly I feel about
it. Here's more of my reasoning:
If we remove Syntax for all generic functions that have Method
Signatures, we are skewing our specification in a certain way. We are
essentially suggesting that users should be able to divine information
about a generic function by looking at one or more methods. But this
is entirely backwards. We should be recommending that people learn
about the generic function first, and then (if necessary) learn about
the individual methods.
∂04-Nov-87 1647 Common-Lisp-Object-System-mailer Re: Issues raised by comments on chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 16:47:32 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 04 NOV 87 16:14:31 PST
Date: 4 Nov 87 16:14 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Issues raised by comments on chapter 2
In-reply-to: Sonya E. Keene, Dick Gabriel
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871104-161431-2659@Xerox>
After pondering Dick's and Sonya's messages, I take back my plea for
non-redundancy (I usually favor redundancy anyway). Syntax is useful,
and I think Method Signatures should include all the arguments,
including keyword names, optionals (as they did for make-instance in the
version of Nov 2). Sonya's characterization of the different questions
answered by Syntax and Method Signatures is helpful.
How do I call this g-f?
--Answered by Syntax
What methods are guaranteed to exist for this g-f?
--Answered by Method Signature
Some other comments:
----
RPG:
One reason to describe the arguments in English is to introduce
some simple noun phrase to use to talk about these arguments.
I also agree with Dick's comment. The redundancy I found slightly
distressing was where Arguments gave type restrictions on specialized
arguments (e.g. The {\it method} argument is a method object.). I am
all in favor of English.
----
RPG:
I propose, then, that the policy of CLOS be that purpose
statements be promoted to apply to generic functions whenever
feasible.
This is the place that the contract for the genric function is
described.
---
Danny writes about CHANGE-CLASS:
``Remove Syntax section, Remove first two lines of Arguments.
The last sentence should read "... and then invokes the first
method with the class returned as value from (symbol-class
symbol)."''
Therefore the purpose of the second method must say something
like:
RPG answers:
``This method invokes CHANGE-CLASS on {\it instance} and
(symbol-class {\it symbol}).''
I agree with Dick. A much better wording of what I intended.
------
RPG:
This brings up the second general point, which is are we going
to require that a pristine CLOS have all and only the methods
described in the specification? Danny's proposed rewrite of the
description of CHANGE-CLASS implies he believes so. I tend to favor
the restriction.
I don't know what I said to generate this idea. I think I believe the
statement above.
But I don't know what criteria are appropriate. What are the criteria
for Common Lisp implementations. Must they have just the types and
functions specified in CTtL. Or is it only the using up of symbols that
count (i.e. Can an implementation have functions and types whose names
the ordinary user doesn't see?). If so, are extra methods (which don't
have names) more like types and functions whose names are in another
package, or like symbols.
For example, CLOS specifies only one method for describe. Could special
methods for describe specialized to pathnames or streams etc. be
defined. Isn't this an implemenation decision relative to putting the
code to discriminate these types in the default method, or in separate
methods?
Finally, I appreciate the spirit in which Dick wrote his response:
The points are made as a response to a message that Danny sent,
but no one should interpret this as picking on his comments, which
simply serve to bring some decisions to light.
∂04-Nov-87 1737 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Nov 87 17:37:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272368; Wed 4-Nov-87 20:37:58 EST
Date: Wed, 4 Nov 87 20:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: format for description of generic functions in chapter 2
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 4 Nov 87 13:18 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>,
<871104105832.6.GREGOR@SPIFF.isl.parc.xerox.com>,
<19871104201026.2.SKEENE@JUNCO.SCRC.Symbolics.COM>,
The message of 4 Nov 87 18:32 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
File-References: SAIL.STANFORD.EDU:NEW.DVI[CLS], SCRC|S:>Moon>LSP].babyl.newest
Message-ID: <19871105013806.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 04 Nov 87 1018 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
I agree with that. However, the new.dvi file that is a sample of the
new format does not seem to be written that way. Lengthy comments about
this below, but first a relatively minor comment on the format.
Too much of the text in a method signature is italicized. Only the
parameter names should be italicized; the parentheses, lambda-list
keywords, and parameter specializer names should be in should be in a
roman font or a typewriter font; this would be more consistent with the
style used elsewhere.
This brings up the second general point, which is are we going to require
that a pristine CLOS have all and only the methods described in the
specification? Danny's proposed rewrite of the description of CHANGE-CLASS
implies he believes so. I tend to favor the restriction.
Currently there is a statement in the introduction to Chapter 2 that
states:
``Any implementation of the \CLOS\ is allowed to provide other methods
for the generic functions described in this chapter.''
Opinions?
I don't think we can reasonably restrict implementations from defining
other methods. Such a restriction would be inutile in any case, since
CLOS programs are obviously allowed to define other methods, and we want
to allow multiple programs to coexist in the same Lisp. Thus any program
that assumes that only the methods defined in this chapter exist is not
going to be a good citizen of the Lisp world. However, what we can say
is something like only the standard methods will be applicable to standard
objects; I think that is not precisely what I mean, but something along
those lines; the intent is that you can add new methods to extend the
behavior of the functions, but you're not supposed to break the behavior
of existing methods.
Date: Wed, 4 Nov 87 10:58 PST
From: Gregor.pa@Xerox.COM
For example,
in print-object, an implementation should be free to have methods on as
many of its pre-defined classes as it likes, but it should not be
allowed to define print-object methods on user-defined classes behind
said user's back.
Yes, that expresses it pretty well.
Date: 04 Nov 87 10:18 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I propose, then, that the policy of CLOS be that purpose statements be promoted
to apply to generic functions whenever feasible.
Whenever 'reasonable' is more like it. For example, the purpose of the
add-method generic function is to add a method to a generic function.
If there is already a similar method an error is signalled. The generic
function is completely updated to know about the new method.
The particular method on (standard-gf standard-method), has some of its
own private behavior as well. For example, it defines what it means for
methods to be similar in this case (same qualifiers and specializers).
It also defines what the lambda-list congruence rules will be.
So its not a matter of whenever feasible, its a matter of reasoning it
out on a case by case basis.
I agree with this. The new.dvi writeup for add-method isn't written this
way, though. More about this below.
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a particular method.
Date: Wed, 4 Nov 87 15:10 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
I like the new method signatures. They give good information in a
concise format. However, I don't believe that a Method Signature is
redundant with Syntax.
I agree. I think the new.dvi format addresses this pretty well.
We should be recommending that people learn
about the generic function first, and then (if necessary) learn about
the individual methods.
I agree 100% and I think the new.dvi format is deficient in this respect.
More about this below.
Date: 04 Nov 87 1532 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
The general format is to start the page with a description of what
the generic function syntax, the method signatures of all methods
specified, the purpose of the generic function, its values, and
remarks about it. The reader should be able to look at the top 4 inches
of a function page and see the generic function lambda list and the
method signatures.
Then there is a line that separates the generic function material from
the method descriptions. Each method description repeats the signature,
adds any method-specific purpose, values, remarks etc.
This sounds very good to me, but the actual file doesn't seem to do it
precisely this way. In particular, the values and remarks are
frequently associated with a particular method where they should be
associated with the generic function as a whole. To me, values have the
same status as arguments, both are part of the interface that the
generic function contracts to supply, and which all methods must conform
to. Sometimes there will be additional method-specific things to say
about arguments or values, and then the method can have one or both of
those fields, but the generic function should always have the arguments
and values fields, and I think the normal case will be that only the
generic function will have these fields.
Another problem is with ordering of fields. In several cases, method
descriptions intervene between two parts of the generic function
description. Often the remarks and the examples come after the methods.
I think this is wrong, especially in light of Sonya's last comment
above; I think the methods should always be at the end, with nothing
after them except the See also field.
Here are some comments on specific pages of the sample new format,
and then I'll address what I think is the general problem with this
new format.
add-method has too much in the method section and not enough in the
generic-function section. In fact I don't think there is anything
to be said about the method specifically; everything that is there
now is the contract of the generic function as a whole, to which all
methods must conform. Gregor disagrees with me about the congruence
part, but not the rest of it.
change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached. The first remarks paragraph, in
contrast, applies just to this method, although I think it's
important for the generic function as a whole to undertake to call
class-changed; the only need for a method-specific remark about
class-changed is to document exactly when class-changed is called
by that particular method. Maybe that detailed remark is unnecessary?
class-changed: I feel this page is an example of good organization, much
better than the other pages. The division between generic-function and
method is exactly right.
class-name: I think the method signature is wrong; surely class-name
works on all classes, not just standard ones. Surely
(class-name (class-of (cons 1 2))) returns something, even though
we don't guarantee that it returns the symbol CONS in all implementations
(it could be the name of an implementation-dependent subclass of CONS).
describe: again I think the method signatures are wrong. What we require
is that there be an applicable method for every object that exists, not
that there be a method on the class T. I complained about this before
when it was in English, I think, and I'm complaining about it again when
it's in method signatures. This started as a typo and now is turning into
an explicit specification. I also don't think we want to require that a
method exist for the exact class standard-object, although I feel less
strongly about that. In the cases of describe and print-object, I think
no method signatures should be listed, and then we should say that the
implementation provides enough predefined methods to assure that there
is always an applicable method, but we do not standardize the precise
parameter specializers of these methods. If we do anything else we
are dictating how the PRINT function is modularized, which is not our
business.
describe: the documentation of the methods here is useless. I suggest
that the format should permit omission of documentation of methods when
the documentation wouldn't say anything.
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
∂04-Nov-87 2046 Common-Lisp-Object-System-mailer Re: Comment on the chapter 2, Version of Nov 2.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Nov 87 20:45:57 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 04 NOV 87 18:05:58 PST
Date: 4 Nov 87 18:05 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Comment on the chapter 2, Version of Nov 2.
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Tue, 3 Nov 87 18:13 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871104-180558-2820@Xerox>
Date: 3 Nov 87 10:29 PST From: Danny Bobrow
<Bobrow.pa@Xerox.COM>
2-21 syntax replace {slot-option}* by [[↑ slot-option]]
and use {:accessor generic-function-name}* {:reader
generic-function-name}* {:initarg name}*
as the last three items of slot-option. Then the
remarks on which options can appear more than once in Arguments
are redundant.
Stylistic comment: I hope we are not changing the style so that
it is impossible for a reader who skips over the BNF syntax
notation to understand the document. I think that would be most
unfortunate. I'd much rather have a little redundancy than make it
necessary to understand the fine points of this increasingly
obscure notation in order to understand the document.
I agree. I just wanted to make the syntax be complete.
2-26 The syntax of defgeneric now shows a lambda-list
as a required argument. I thought :lambda-list was supposed to
be a keyword argument. Similarly for generic-labels,
generic-flet, generic-function, and with-added-methods. When
there are method descriptions provided, the lambda-list is
often redundant, and hence can be a cause for mistakes. My
notes from the meeting show that there was no required
lambda-list, at least for the generic-labels, generic-flet,
generic-function, and with-added-methods. Hence by extension,
there should not be a required lambda-list in defgeneric.
I don't think we agreed in the meeting to remove these
lambda-lists. My copies of the draft documents from the meeting
show the lambda-list (along with a bunch of other stuff) missing in
the first version of some writeups, but present in the second
version that we produced after discussion and rationalization of
the syntax of all the things having to do with generic functions.
Perhaps you got mixed up on which version was newer? There are no
dates on these pages but at the meeting I wrote "old" or something
on the older ones.
You are probably right about the cause for the mixup. But the issue
remains whether lambda-list should be required. For most uses of these
forms, I can't see really wanting a lambda-list e.g. just
(ensure-generic-function 'foo) followed by defmethods, or where one has
the methods for a generic-flet (etc) and hence doesn't need the
lambda-list unless the :argument-precedence-order option is used. I
still can't remember an argument for making it required. Can you remind
me please.
∂05-Nov-87 0919 Common-Lisp-Object-System-mailer lambda-list in defgeneric
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:19:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272759; Thu 5-Nov-87 12:19:47 EST
Date: Thu, 5 Nov 87 12:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: lambda-list in defgeneric
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871104-180558-2820@Xerox>
Message-ID: <19871105172001.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
I'll try a one-word answer, and if that doesn't work, I'll try to
find the time to write a detialed explanation.
&key.
∂05-Nov-87 0924 Common-Lisp-Object-System-mailer lambda-list in defgeneric, generic-flet, etc.
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:24:51 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272765; Thu 5-Nov-87 12:25:42 EST
Date: Thu, 5 Nov 87 12:25 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: lambda-list in defgeneric, generic-flet, etc.
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871104-180558-2820@Xerox>
Supersedes: <19871105172001.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19871105172557.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Never mind the one-word answer.
It's clear that the lambda-list is needed sometimes. It's needed for
&key, it's needed for :argument-precedence-order, and it's needed when
no methods are specified. It's also needed if the lambda-list serves
as documentation and the most appropriate and explanatory parameter names
are different for the generic function than for the method.
The question is whether to allow the lambda-list to be omitted in some
cases.
You seem to be concerned about the redundancy when there is exactly one
method specified. Obviously if there are no methods there is no redundant
lambda-list, and if there is more than one method specified in the
defgeneric or generic-flet or what have you, there is redundancy anyway.
My feeling is that making the syntax more cumbersome and less consistent,
by making the lambda-list optional, in order to eliminate this tiny bit of
redundancy, is not worthwhile. Also I think the redundancy can be justified
as a valuable sanity check.
Another interesting piece of experience is that the syntax of :method in
defgeneric in Flavors tries to avoid such redundancy. It has a lambda-list
for the defgeneric, but no lambda-list for the methods, just a parameter
specializer name (to use CLOS terminology). I think that experience with
this has shown that it was a bad idea and that it would have been better to
have the redundancy for the sake of a more consistent syntax.
∂05-Nov-87 0950 Common-Lisp-Object-System-mailer format for description of generic functions in chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 09:50:35 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 NOV 87 09:44:49 PST
Date: Thu, 5 Nov 87 09:44 PST
From: Gregor.PA@Xerox.COM, Bobrow.PA@Xerox.COM
Sender: Gregor.pa@GRAPEVINE.isl.parc.xerox.com
Subject: format for description of generic functions in chapter 2
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871105013806.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
File-References: DOMAIN|SAIL.STANFORD.EDU:NEW.DVI[CLS],
SCRC|S:>Moon>LSP].babyl.newest
Message-ID: <871105094413.1.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Wed, 4 Nov 87 20:38 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
First off, we want to say that we think the new method signature stuff
is a good idea and looks good overall.
Too much of the text in a method signature is italicized. Only the
parameter names should be italicized; the parentheses, lambda-list
keywords, and parameter specializer names should be in should be in a
roman font or a typewriter font; this would be more consistent with the
style used elsewhere.
Right.
I don't think we can reasonably restrict implementations from defining
other methods. Such a restriction would be inutile in any case, since
CLOS programs are obviously allowed to define other methods, and we want
to allow multiple programs to coexist in the same Lisp. Thus any program
that assumes that only the methods defined in this chapter exist is not
going to be a good citizen of the Lisp world. However, what we can say
is something like only the standard methods will be applicable to standard
objects; I think that is not precisely what I mean, but something along
those lines; the intent is that you can add new methods to extend the
behavior of the functions, but you're not supposed to break the behavior
of existing methods.
Right, this is hard to word, but we are going to have to make some stab
at it. We will try to take a stab at this later.
Date: Wed, 4 Nov 87 10:58 PST
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a
particular method.
I (Gregor) still disagree with you about this. More in a separate
message.
This sounds very good to me, but the actual file doesn't seem to do it
precisely this way. In particular, the values and remarks are
frequently associated with a particular method where they should be
associated with the generic function as a whole. To me, values have the
same status as arguments, both are part of the interface that the
generic function contracts to supply, and which all methods must conform
to. Sometimes there will be additional method-specific things to say
about arguments or values, and then the method can have one or both of
those fields, but the generic function should always have the arguments
and values fields, and I think the normal case will be that only the
generic function will have these fields.
Another problem is with ordering of fields. In several cases, method
descriptions intervene between two parts of the generic function
description. Often the remarks and the examples come after the methods.
I think this is wrong, especially in light of Sonya's last comment
above; I think the methods should always be at the end, with nothing
after them except the See also field.
Right.
Here are some comments on specific pages of the sample new format,
and then I'll address what I think is the general problem with this
new format.
add-method has too much in the method section and not enough in the
generic-function section. In fact I don't think there is anything
to be said about the method specifically; everything that is there
now is the contract of the generic function as a whole, to which all
methods must conform. Gregor disagrees with me about the congruence
part, but not the rest of it.
Not exactly. We think both the second paragraph of the arguments
section and the second paragraph of the remarks section should be put
under method remarks. Briefly, the point is that a user should be free
to define a new kind of method that say doesn't have qualifiers or a new
kind of generic function which uses different congruence rules.
The value returned should be in the generic function, its has to be eq
to the first argument.
change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached.
Right
The first remarks paragraph, in
contrast, applies just to this method, although I think it's
important for the generic function as a whole to undertake to call
class-changed; the only need for a method-specific remark about
class-changed is to document exactly when class-changed is called
by that particular method.
Right
Maybe that detailed remark is unnecessary?
It is needed
class-changed: I feel this page is an example of good organization, much
better than the other pages. The division between generic-function and
method is exactly right.
Right
class-name: I think the method signature is wrong; surely class-name
works on all classes, not just standard ones. Surely
(class-name (class-of (cons 1 2))) returns something, even though
we don't guarantee that it returns the symbol CONS in all implementations
(it could be the name of an implementation-dependent subclass of
CONS).
In the current meta object draft, all those classes are (believe it or
not), subclasses of standard class. So, this is right according to
that. We had a long discussion with Pierre Cointe about this, that is
included in the meta-object draft we are (finally) writing.
describe: again I think the method signatures are wrong. What we require
is that there be an applicable method for every object that exists, not
that there be a method on the class T. I complained about this before
when it was in English, I think, and I'm complaining about it again when
it's in method signatures. This started as a typo and now is turning into
an explicit specification. I also don't think we want to require that a
method exist for the exact class standard-object, although I feel less
strongly about that. In the cases of describe and print-object, I think
no method signatures should be listed, and then we should say that the
implementation provides enough predefined methods to assure that there
is always an applicable method, but we do not standardize the precise
parameter specializers of these methods. If we do anything else we
are dictating how the PRINT function is modularized, which is not our
business.
describe: the documentation of the methods here is useless. I suggest
that the format should permit omission of documentation of methods when
the documentation wouldn't say anything.
Right, Right, Right...
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
Its true that this new breakout causes us to confront some meta-object
stuff which we don't really want to have to work out in the next 5 days.
But, it may be alright if we just take our best stab at it and then fix
it up later. Here's why. We believe that for the time being, the only
kind of programming we are really sanctioning is programming that calls
these generic functions (in cases like add-method). In these cases, we
should take our best shot, but if in the course of writing the meta spec
we decide we need to move something from method to gf or vice versa we
can. Because as far as the user who just calls generic functions like
add-method, the behavior of the generic function as a whole will be
unchanged. As a point of strategy, where we are unsure, behavior should
be ascribed to the generic function rather than the one of the methods.
Generic functions like describe and print-object are different, these we
have to try and get right this go around. Thats probably tractable,
Moon's comments above seem to hit it on the nose.
-------
∂05-Nov-87 1231 Common-Lisp-Object-System-mailer ambiguity in defgeneric and method descriptions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 12:30:32 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 272978; Thu 5-Nov-87 15:31:19 EST
Date: Thu, 5 Nov 87 15:31 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: ambiguity in defgeneric and method descriptions
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <19871105203106.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Page 2-29: the defgeneric section, the first two paragraphs under
Remarks:
The first paragraph is:
"If a method already exists on the given generic function with the same
parameter specializers and the same qualifers, defgeneric replaces the
existing method with the one now being defined."
My question is, "the same as what?" I suggest clarifying it along these
lines:
"If a method already exists on the given generic function with the same
parameter specializers and the same qualifers as any method description
given in this defgeneric form, that existing method is replaced with the
one now being defined."
The second paragraph is:
"If ano method descriptions are specified and a generic function of the
same name does not already exist, a generic function with no methds is
created."
That makes perfect sense, but I think it brings up another point to
clarify. What happens if no method descriptions are specified in this
defgeneric, but there is an existing generic function with methods?
Have we decided what happens then? I don't remember any discussion
about it.
In the old days of defgeneric (before method descriptions), we said that
no methods were affected when a generic function was redefined. If
that still holds in the current scheme, the users might be faced with an
interesting pitfall. If the old defgeneric included a method
description and the new one doesn't, then the Lisp world will contain a
method, but there won't be any source of that method.
The alternative would be to follow the model of defclass; if the old
defclass defined readers or accessors and the new defclass does not,
during the redefinition those old methods and generic functions go away.
We could make old methods that were defined by the :method option to
defgeneric go away, if the new defgeneric doesn't define those methods.
Whichever one is right, it's worth another Remark.
∂05-Nov-87 1545 Common-Lisp-Object-System-mailer Re: lambda-list in defgeneric, generic-flet, etc.
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 15:44:53 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 NOV 87 15:38:10 PST
Date: 5 Nov 87 15:37 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: lambda-list in defgeneric, generic-flet, etc.
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Thu, 5 Nov 87 12:25 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Bobrow.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871105-153810-1563@Xerox>
Thank you for the longer answer. I find the arguments convincing enough
(that is enough to stop arguing). I am convinced now that it is SMOT
(small matter of taste), and with you, Dick and Gregor agreeing, my
taste buds must be off.
danny
∂05-Nov-87 1623 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 16:23:10 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 05 NOV 87 16:18:32 PST
Date: 5 Nov 87 16:18 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: ambiguity in defgeneric and method descriptions
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Thu, 5 Nov 87 15:31 EST
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871105-161832-1644@Xerox>
That makes perfect sense, but I think it brings up another
point to clarify. What happens if no method descriptions are
specified in this defgeneric, but there is an existing generic
function with methods? Have we decided what happens then? I don't
remember any discussion about it.
In the old days of defgeneric (before method descriptions), we
said that no methods were affected when a generic function was
redefined. If that still holds in the current scheme, the users
might be faced with an interesting pitfall. If the old
defgeneric included a method description and the new one doesn't,
then the Lisp world will contain a method, but there won't be any
source of that method.
The alternative would be to follow the model of defclass; if
the old defclass defined readers or accessors and the new defclass
does not, during the redefinition those old methods and generic
functions go away. We could make old methods that were defined by
the :method option to defgeneric go away, if the new defgeneric
doesn't define those methods.
Whichever one is right, it's worth another Remark.
I think that it is important thatold methods stay around. Consider two
applications that define a generic function. They are designed to work
independently, and also together. Hence each will have a defgeneric
(compatible of course, since they were meant to work together), and each
will independently define methods, say with their :method options. The
fact the the second one does not have the same methods as the first
should not invalidate the first, I think. The model I have is that
defgeneric updates the generic function with respect to its metaclass,
method class, etc. but does not affect existing methods. An error is
signalled for any compatibility problem of course. This is the same as
the old model. As you can see in some cases there are sources for the
other methods, and in others not (what happens now when you simply edit
a file to remove a defmethod or defun form?)
danny
∂05-Nov-87 1631 Common-Lisp-Object-System-mailer State of Affairs
To: common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I've completed the major pass on chapter 1 that Gregor's comments
required. The result so cleaned it up that I made a second major
pass and I now believe chapter 1 to be very close to complete.
The state of affairs with chapter 2 now greatly concerns me.
To illustrate this, let me comment on one of the comments that Moon
made about the selected function pages that we put out for comment.
Regarding CHANGE-CLASS Moon writes:
``change-class: the second remarks paragraph is a remark about the
generic function as a whole, and has nothing to do with the specific
method to which it is attached.''
That remarks paragraph states:
``This method on {\bf change-class} has several semantic difficulties.
First, it performs a destructive operation that can be invoked within a
method on an instance that was used to select that method. When multiple
methods are involved because methods are being combined,
the methods currently executing or about to be executed
may no longer be applicable. Second, some implementations might use compiler
optimizations of slot access, and when the class of an instance is
changed the assumptions the compiler made might be violated.
This implies that a programmer must not use this method on {\bf
change-class} inside a method if any methods for that generic function
access any slots, or else the results are undefined.''
The semantic problem is that the class of the instance is altered while
the generic function is operating. One can argue that this is a change of
identity in some semantic domain. The fact that this is related to a
``destructive operation'' depends on the representation of the instance,
which depends on its metaclass which depends on the fact that the instance
is an instance of standard-object, because its class is standard-class.
This appears to be something specific to this method or constellation of
methods. The same reasoning holds for the mention of the compiler messing
around with optimizations of slot access - I've heard some metaclasses
say ``what's a slot?''
Therefore, the semantic difficulty is best expressed in both places:
There is a semantic difficulty with the generic function because we choose
to specify that whatever else it does it alters the class of an instance.
And this can happen in the middle of a method combination that might
involve running those other methods on a now-non-applicable instance.
This method happens to compound the problem by messing with the
representation in some way, invalidating the compiler's assumptions.
Therefore, the comment Moon makes serves to raise a much harder issue of
how close to the bone we cut our distinctions.
Notice that LGD and I gave this some amount of thought, because the
Purpose entry for the generic function states that the generic function
changes the class, while the one for this main method talks about the
destructiveness of the operation.
What has to be pointed out is that even if we choose to back out of
any changes made to the format of chapter 2 in the last 4 days (this amounts
to little or no work), we now know that the wording that we have been using
is very imprecise with respect to a level of precision to which we could
rationally aspire. This Remark, if left in a version of chapter 2 with
the older format, mixes up the general activities and meaning of a very
abstract entity (a generic function) with the activities and meaning of
a specific method.
Let me state at this point that LGD and I have neither interest nor motivation
to want to take a shot at sorting this out by ourselves. And I can easily
see this group, even in a face-to-face meeting, arguing for weeks about
the wording and exact breakdown of what is said when and where.
What's worse, our selection procedure was to pick the first 4 or 5
function pages in chapter 2 to try, not the hardest 4 or 5, and I'm not
sure that we could totally resolve CHANGE-CLASS in under 4 days of
discussion at the current bandwidth.
Therefore, I leave it to you folks to decide how to proceed.
-rpg-
∂05-Nov-87 1727 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 5 Nov 87 17:26:39 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae08957; 5 Nov 87 16:34 EST
Received: from csl.ti.com by RELAY.CS.NET id ad24858; 5 Nov 87 16:32 EST
Received: from Jenner by tilde id AA28983; Thu, 5 Nov 87 15:08:06 CST
Message-Id: <2772133532-6702890@Jenner>
Date: Thu, 5 Nov 87 15:05:32 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: format for description of generic functions in chapter 2
In-Reply-To: Msg of Thu, 5 Nov 87 09:44 PST from Gregor.PA@xerox.com, Bobrow.PA@xerox.com
Actually, I disagree with one detail of what Gregor said. I can't understand
why lambda-list congruence should be restricted to standard generic functions
and standard methods. To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see how
generic functions could work or users could call them if there wasn't
lambda-list congruence. Thus I think congruence is part of the contract of
add-method, and should not be demoted to association with a
particular method.
I (Gregor) still disagree with you about this. More in a separate
message.
I will be interested in seeing what prompted Gregor to disagree. It
seems to me that it is bad if you have to know the class of a generic
function, and find out about the lambda congruence rule for this class,
in order to know that your program is calling it properly. I doubt that
you will gain much power from changing the lambda list congruence rule
and it seems that this "flexibility" will bring confusion.
Here's the big problem with this new breakout of methods and generic
functions: We are uncovering a significant amount of confusion about
what is the contract of a generic function, versus what is a property
of particular methods for that generic function. In effect all of
the issues and uncertainties surrounding meta-objects have suddenly
leaked into the part of the document that we thought was almost
finished. I'm really opposed to that because I think it sets us back
a long way. It's really not necessary to resolve all those issues
to get something that is entirely useful to someone who is just going
to call these generic functions and not define new methods for them.
On the other hand, I do think the introduction of the method signatures
was a good idea, and I think the format as described in the quotation
from RPG above is a good idea. If we can keep the documentation in the
style of the sample class-changed writeup, I'll be happy with the new
format, but if we're going to get bogged down in all these modularity
issues, I want no part of it.
Its true that this new breakout causes us to confront some meta-object
stuff which we don't really want to have to work out in the next 5 days.
But, it may be alright if we just take our best stab at it and then fix
it up later. Here's why. We believe that for the time being, the only
kind of programming we are really sanctioning is programming that calls
these generic functions (in cases like add-method). In these cases, we
should take our best shot, but if in the course of writing the meta spec
we decide we need to move something from method to gf or vice versa we
can. Because as far as the user who just calls generic functions like
add-method, the behavior of the generic function as a whole will be
unchanged. As a point of strategy, where we are unsure, behavior should
be ascribed to the generic function rather than the one of the methods.
I like this strategy. I don't have any problems with the agreement
reached in each case.
Patrick.
∂05-Nov-87 1817 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 18:17:23 PST
Received: from Semillon.ms by ArpaGateway.ms ; 05 NOV 87 18:17:08 PST
Date: Thu, 5 Nov 87 18:16 PST
From: Gregor.pa@Xerox.COM
Subject: CALL-NEXT-METHOD example
To: LGD@SAIL.STANFORD.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <871105181642.6.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Here is an example which could be used for the call-next-method section.
Its somewhat of a silly example, but I believe it captures several
important points about call-next-method. Namely its basic behavior, how
it defaults the argument when no arguments are passed, that it is a true
lexical function, and that it is possible to pass it arguments,
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(a b c)) ==> (A B C)
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
∂05-Nov-87 1927 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 19:27:14 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 273360; Thu 5-Nov-87 22:26:51 EST
Date: Thu, 5 Nov 87 22:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CALL-NEXT-METHOD example
To: Gregor.pa@Xerox.COM
cc: LGD@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <871105181642.6.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871106032706.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 5 Nov 87 18:16 PST
From: Gregor.pa@Xerox.COM
Here is an example which could be used for the call-next-method section.
Its somewhat of a silly example, but I believe it captures several
important points about call-next-method. Namely its basic behavior, how
it defaults the argument when no arguments are passed, that it is a true
lexical function, and that it is possible to pass it arguments,
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(a b c)) ==> (A B C)
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
I don't see why (collect '(a b c)) isn't invalid for the same
reason. The list method becomes inapplicable in the recursive call.
∂05-Nov-87 1948 Common-Lisp-Object-System-mailer Re: ambiguity in defgeneric and method descriptions
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Nov 87 19:48:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 273383; Thu 5-Nov-87 22:48:30 EST
Date: Thu, 5 Nov 87 22:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: ambiguity in defgeneric and method descriptions
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871105-161832-1644@Xerox>
Message-ID: <19871106034841.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 5 Nov 87 16:18 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
The alternative would be to follow the model of defclass; if
the old defclass defined readers or accessors and the new defclass
does not, during the redefinition those old methods and generic
functions go away. We could make old methods that were defined by
the :method option to defgeneric go away, if the new defgeneric
doesn't define those methods.
Whichever one is right, it's worth another Remark.
I agree that it's worth a Remark.
I think that it is important that old methods stay around. Consider two
applications that define a generic function. They are designed to work
independently, and also together. Hence each will have a defgeneric
(compatible of course, since they were meant to work together), and each
will independently define methods, say with their :method options. The
fact the the second one does not have the same methods as the first
should not invalidate the first, I think.
I have to agree with this argument, even though I feel that such a pair
of applications is poorly structured and should have a shared "definitions"
module that contains one defgeneric. Remember we're not forcing you to put
all your method definitions into :method options (except in generic-flet,
generic-labels, and generic-function).
The model I have is that
defgeneric updates the generic function with respect to its metaclass,
method class, etc. but does not affect existing methods.
Except it does affect existing methods if :method is specified, so this
argument isn't going to tell us anything about the case that Sonya
brought up. Instead we have to say: "Note, defgeneric can add methods,
and can replace methods, but never removes a method."
An error is
signalled for any compatibility problem of course. This is the same as
the old model. As you can see in some cases there are sources for the
other methods, and in others not (what happens now when you simply edit
a file to remove a defmethod or defun form?)
That depends on how smart your editor is. But surely if it understands
removing a defmethod it can understand removing a :method option from a
defgeneric.
∂05-Nov-87 2111 Common-Lisp-Object-System-mailer Chapter 1 typos.
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 5 Nov 87 21:11:35 PST
Received: from relay2.cs.net by RELAY.CS.NET id ac10117; 5 Nov 87 17:46 EST
Received: from csl.ti.com by RELAY.CS.NET id aa25269; 5 Nov 87 17:45 EST
Received: from Jenner by tilde id AA00248; Thu, 5 Nov 87 15:57:44 CST
Message-Id: <2772136524-6882684@Jenner>
Date: Thu, 5 Nov 87 15:55:24 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Chapter 1 typos.
1-12 First defclass, ) missing.
1-24 Second paragraph, "When a method combination type is defined using
the short form of DEFINE-METHOD-COMBINATION, primary methods are defined
to include not only the methods qualified with the same name of the type
of method combination, but certain others as well". This is not true.
Primary methods include only those qualified with the name of the method
combination type.
Patrick.
∂06-Nov-87 1017 Common-Lisp-Object-System-mailer Defgeneric affects methods?
To: Common-lisp-object-system@SAIL.Stanford.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
``Except it does affect existing methods if :method is specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
-rpg-
∂06-Nov-87 1109 Common-Lisp-Object-System-mailer CALL-NEXT-METHOD example
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 11:09:16 PST
Received: from Semillon.ms by ArpaGateway.ms ; 06 NOV 87 11:07:01 PST
Date: Fri, 6 Nov 87 11:06 PST
From: Gregor.pa@Xerox.COM
Subject: CALL-NEXT-METHOD example
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, LGD@SAIL.STANFORD.EDU,
Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <19871106032706.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871106110624.7.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
Date: Thu, 5 Nov 87 22:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I don't see why (collect '(a b c)) isn't invalid for the same
reason. The list method becomes inapplicable in the recursive call.
Oops, your right. What I spaced on at the time was that I wasn't change
the applicable set of next methods so it was OK. Should that in fact be
the rule?
If not, here is a corrected example.
(defmethod collect (thing) thing)
(defmethod collect ((n number))
(let ((l ()))
(dotimes (i n)
(push (call-next-method) l))
(reverse l)))
(defmethod collect ((l list))
(mapcar #'call-next-method l))
(collect 5) ==> (5 5 5 5 5)
(collect '(() () ())) ==> (() () ())
;;; But note the following erroneous use of call-next-method.
;;; This example would cause an error to be signalled because
;;; the argument which is supplied to call-next-method would
;;; cause a different set of methods to be applicable.
(collect '(1 2 3))
-------
∂06-Nov-87 1229 Common-Lisp-Object-System-mailer setf of class-name
Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 6 Nov 87 12:29:23 PST
Received: from JUNCO.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 185747; Fri 6-Nov-87 15:29:00 EST
Date: Fri, 6 Nov 87 15:28 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: setf of class-name
To: common-lisp-object-system@SAIL.STANFORD.EDU
Included-msgs: <19871023233437.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
The message of 23 Oct 87 19:34 EDT from Moon@STONY-BROOK.SCRC.Symbolics.COM,
The message of 23 Oct 87 19:34 EDT from David A. Moon
Included-References: <871023-154303-1550@Xerox>
Message-ID: <19871106202846.9.SKEENE@JUNCO.SCRC.Symbolics.COM>
As far as I know, we still believe that setf of class-name should work,
but the writeup of class-name in Chapter 2 doesn't mention this.
The following forwarded message is the last I've seen on this topic, and
it looks like both Dave and Danny believe setf of class-name belongs in
the spec.
----------------
Date: Fri, 23 Oct 87 19:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: More on Class names
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <871023-154303-1550@Xerox>
Date: 23 Oct 87 15:42 PDT
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
It should be stated in chapter one that a many-one association from
symbols to classes is implemented by symbol-class and (setf
symbol-class). An INDEPENDENT association from class to symbol is
maintained by class-name and (setf class-name). Neither of these setf
functions effects the other association. defclass is specified to do
both (setf symbol-class) and (setf class-name).
I agree.
∂06-Nov-87 1343 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 13:43:18 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 06 NOV 87 13:31:28 PST
Date: 6 Nov 87 13:31 PST
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Defgeneric affects methods?
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 06 Nov 87
10:17 PST
To: Common-lisp-object-system@SAIL.Stanford.EDU
Message-ID: <871106-133128-1483@Xerox>
``Except it does affect existing methods if :method is
specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
I think that this is an example where documentation indirection would
pay off. Describe what happens when one evaluates a defgeneric with no
:method options, and thee is an existing generic function. No existing
methods on the existing generic function is changed.
Then state that defgeneric with :method options is equivalent to a
defgeneric with no :method options follwoed by a set of defmethods. We
have said what happens there as well. Similar methods get replaced.
∂06-Nov-87 1352 Common-Lisp-Object-System-mailer Re: Defgeneric affects methods?
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Nov 87 13:52:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 274069; Fri 6-Nov-87 16:51:53 EST
Date: Fri, 6 Nov 87 16:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defgeneric affects methods?
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871106-133128-1483@Xerox>
Message-ID: <19871106215202.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 6 Nov 87 13:31 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
RPG:
``Except it does affect existing methods if :method is
specified, so....''
Here is an issue brought up by wording problems: do you mean
that defgeneric affects the set of existing methods (such as
replacing some of them) or that defgeneric affects some individuals
because when one is ``replaced'' a method is destructively modified?
I think that this is an example where documentation indirection would
pay off. Describe what happens when one evaluates a defgeneric with no
:method options, and thee is an existing generic function. No existing
methods on the existing generic function is changed.
Then state that defgeneric with :method options is equivalent to a
defgeneric with no :method options follwoed by a set of defmethods. We
have said what happens there as well. Similar methods get replaced.
I agree with this approach. I think this is the same as what the document
already says, provided we remove the one offending remark.
∂06-Nov-87 1731 Common-Lisp-Object-System-mailer Re: format for description of generic functions in chapter 2
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Nov 87 17:31:35 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 06 NOV 87 17:25:27 PST
Date: 6 Nov 87 17:25 PST
From: Masinter.pa@Xerox.COM
Subject: Re: format for description of generic functions in chapter 2
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
message of Wed, 4 Nov 87 20:38 EST
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871106-172527-1861@Xerox>
"To me lambda-list congruence seems equally applicable
to all generic functions and methods, and furthermore it's hard to see
how
generic functions could work or users could call them if there wasn't
lambda-list congruence. . . ."
There were numerous discussions of alternate rules for lambda-list
congruence than the ones that made it into the spec. Generic functions
could implicitly assume that they were defined with &rest, for example,
yet allow some methods to have &REST and others &KEY or even a set of
&OPTIONAL arguments. Allowing the number of arguments to vary by class
seems possible, too, although it might require a run-time test at method
entry to determine if the generic function handed on too many arguments
for that particular method.
∂09-Nov-87 1452 Common-Lisp-Object-System-mailer Current State of CLOS Draft
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 14:52:20 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 9 Nov 87 14:40:25-PST
Received: from hplms2 by hplabs.HP.COM with SMTP ; Mon, 9 Nov 87 14:45:00 PST
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 9 Nov 87 14:44:45 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 9 Nov 87 15:44:19 pst
To: common-lisp-object-system@sail.stanford.edu
Subject: Current State of CLOS Draft
X-Mailer: mh6.5
Date: Mon, 09 Nov 87 15:44:12 MST
Message-Id: <2268.563496252@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
Is the current CLOS draft on sail in tex-able source form? If so, are
the files the usual ones, or different?
Also, has the location, agenda, and time for the meeting next Monday in
Fort Collins been set?
Thanks.
jak
∂10-Nov-87 1402 Common-Lisp-Object-System-mailer Agenda for X3J13
To: common-lisp-object-system@SAIL.Stanford.EDU
CC: mathis@C.ISI.EDU
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you know, we ran into a brick wall last week with the specification.
The problem is with the question of how much the meta-object level
should influence the format and content of chapter 2. The issue is
how to decide what to say about the specification of a generic function
versus what to say about specific methods.
I think there is no question that this level of detail is worth
specifying, but the question was how much to try to do before the X3
meeting.
It turns out that the very question itself and our initial consideration
of it broke our stride enough that we will not be able to have
an extensive discussion at X3 because we will not have coherent
draft of chapters 1 and 2 in the hands of the X3 members soon enough.
Therefore, the following have been decided:
1. There will be no CLOS subcommittee meeting in Colorado.
2. Danny Bobrow, Sonya Keene, and Linda DeMichiel will not attend the meeting.
3. Gregor will present an overview of the decisions we made, such as
initialization, class redefinition, etc.
I'm sorry if this necessitates a change in your travel plans.
-rpg-
∂11-Nov-87 0757 Common-Lisp-Object-System-mailer Agenda for X3J13
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Nov 87 07:57:29 PST
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 277003; Wed 11-Nov-87 10:28:24 EST
Date: Wed, 11 Nov 87 10:28 EST
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Agenda for X3J13
To: RPG@SAIL.Stanford.EDU
cc: common-lisp-object-system@SAIL.Stanford.EDU, mathis@C.ISI.EDU
In-Reply-To: The message of 10 Nov 87 17:02 EST from Dick Gabriel <RPG@SAIL.Stanford.EDU>
Message-ID: <19871111152820.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Date: 10 Nov 87 1402 PST
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
As you know, we ran into a brick wall last week with the specification.
The problem is with the question of how much the meta-object level
should influence the format and content of chapter 2. The issue is
how to decide what to say about the specification of a generic function
versus what to say about specific methods.
I think there is no question that this level of detail is worth
specifying, but the question was how much to try to do before the X3
meeting.
It turns out that the very question itself and our initial consideration
of it broke our stride enough that we will not be able to have
an extensive discussion at X3 because we will not have coherent
draft of chapters 1 and 2 in the hands of the X3 members soon enough.
Therefore, the following have been decided:
1. There will be no CLOS subcommittee meeting in Colorado.
2. Danny Bobrow, Sonya Keene, and Linda DeMichiel will not attend the meeting.
I am going to the X3J13 meeting.
3. Gregor will present an overview of the decisions we made, such as
initialization, class redefinition, etc.
I'm sorry if this necessitates a change in your travel plans.
-rpg-
∂11-Nov-87 1441 Common-Lisp-Object-System-mailer making gf lambda lists
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 14:41:00 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 14:41:46 PST
Date: Wed, 11 Nov 87 14:41 PST
From: Gregor.pa@Xerox.COM
Subject: making gf lambda lists
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111144109.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I believe that we are going to want to introduce a support function
called something like:
make-generic-function-lambda-list-from-specialized-method-lambda-list
This function will make it easier for programmers who are constructing
their own methods and generic functions to get themselves a congruent
generic function lambda list. This functions will strip out
specializers and optional defaults and remove uses of &key and &aux (and
anything else I might have forgotten).
Can anyone think of a better name for this function?
Can anyone think of a worse name?
-------
∂11-Nov-87 1451 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 14:51:39 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 14:51:59 PST
Date: Wed, 11 Nov 87 14:51 PST
From: Gregor.pa@Xerox.COM
Subject: scope of call-next-method
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111145127.4.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
This message concerns the scope of call-next-method and next-method-p.
Recent drafts of the spec say that the scope of these functions include
the default value forms for optional and keyword arguments. I believe
that the scope of these should include only the body of the method.
I don't see how what the spec currently says can work. The problem is
that call-next-method is defined to have access to the bindings of the
arguments to the method. But if call-next-method is called during the
process of doing those bindings what arguments will it have access to?
What arguments will it pass to the next method? I believe the only
model that can work reasonably is that call next method is defined only
within the body of the method.
So, my model (and proposal) is that:
(defmethod foo ((x boat))
(body x))
expands to
.
.
(lambda (x)
(flet ((call-next-method (&rest args) ...)
(next-method-p () ...))
(body x)))
I realize that we could make the rules different for call-next-method
and next-method-p, but I think that would be gratuitous complexity and
incompatibility.
-------
∂11-Nov-87 1514 Common-Lisp-Object-System-mailer optimization in the spec
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 15:06:08 PST
Received: from Semillon.ms by ArpaGateway.ms ; 11 NOV 87 15:02:55 PST
Date: Wed, 11 Nov 87 15:02 PST
From: Gregor.pa@Xerox.COM
Subject: optimization in the spec
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
In the latest draft of the spec, there are several places which
explicitly address legal optimizations an implementation might perform.
I find these somewhat confusing, and I think that instead we might want
to do the following:
1- Have an general, well worked out statement about what kinds of
optimization are legal in CLOS implementations. This statement
would be 'the optimization law'.
2- Have an appendix or implementation notes in the document reflecting
places in the design where the intent was to allow optimizations
that are in accordance with the 'the optimization law'.
As a start on this, here is a first crack on the law.
In order to insure program portability, there are strict rules which
must be followed when doing optimization of CLOS implementations. The
rules governing when error checking and signalling can be optimized away
have already been covered. Except where it is explicitly stated that
under certain compilation conditions it is permissible not to signal an
error, the rule governing optimizations is that no optimization can
change the behavior of a program. All optimizations must preserve the
semantics of the CLOS.
Examples of legal optimizations include:
Where the system can determine what methods will be called for a
particular invocation of a generic function, it might compile out the
method lookup.
Where methods have been declared inline (whatever that means) or are
system supplied methods, the system might compile calls (like the one
above) out entirely.
This is just rough, but I hope you can see what I am trying to capture.
That is that I am trying to make it clear that except where we say so
explicitly, a program can be sure that optimizations won't have weird
semantics. For example, the current text that talks about optimizing
initarg defaulting makes it sound like I could write a program which
could tell that some initarg defaulting had been optimized out. We need
to make it clear that no user program will be able to detect
optimization (except for the stuff about an error should be signalled).
-------
∂12-Nov-87 1330 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Nov 87 13:30:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 12 NOV 87 10:56:14 PST
Date: Thu, 12 Nov 87 10:55 PST
From: Gregor.pa@Xerox.COM
Subject: scope of call-next-method
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871112172228.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871112105535.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I would still rather have call-next-method only be valid in the body of
the method and let users who want to do defaulting using it do the
defaulting by hand in the obvious way. I believe that the model that
defmethod wrap an flet around their body is a great deal simpler than
the model required to explain the behavior you propose. Just compare:
(defmetod foo ((x class))
(body x))
call-next-method only available in body:
.
#'(lambda (x)
(flet ((call-next-method (&rest r) ..))
(body x)))
.
call-next-method available in body and default value forms:
.
#'(lambda (&rest #:c-n-m-arguments)
(flet ((call-next-method (&rest #:c-n-m-arguments)
(apply ... (or #:c-n-m-arguments #:arguments))))
(apply #'(lambda (x)
(body x))
#:c-n-m-arguments)))
.
-------
∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Nov 87 14:11:24 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278010; Thu 12-Nov-87 12:22:49 EST
Date: Thu, 12 Nov 87 12:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: scope of call-next-method
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111145127.4.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871112172228.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 11 Nov 87 14:51 PST
From: Gregor.pa@Xerox.COM
This message concerns the scope of call-next-method and next-method-p.
Recent drafts of the spec say that the scope of these functions include
the default value forms for optional and keyword arguments. I believe
that the scope of these should include only the body of the method.
I don't see how what the spec currently says can work. The problem is
that call-next-method is defined to have access to the bindings of the
arguments to the method.
No. Call-next-method has access to the arguments. It explicitly does not
access the bindings of the parameters (-not- arguments) of the method.
But if call-next-method is called during the
process of doing those bindings what arguments will it have access to?
What arguments will it pass to the next method?
I think you've been misled by the arguments/parameters terminology.
Even though I'm pretty sure CLtL uses those terms consistently, and I
think the CLOS spec does as well, in informal talk people still often
get them mixed up, and the two words sound so similar that this is not
surprising, especially since other languages use other terminology.
Here's a simple example of a way to implement it, although I imagine
most implementations would find another way that is less simple but
more efficient in that particular implementation. Several obvious
improvements to the below will immediately spring to your mind.
For instance, it isn't necessary to use &rest.
(defmethod foo ((x boat) &optional (y (call-next-method)))
(body x y))
==>
(add-method ...
(make ...
#'(lambda (... &rest #:arguments)
(flet ((call-next-method (&rest #:c-n-m-arguments)
(apply ... (or #:c-n-m-arguments #:arguments)))
(next-method-p () ...))
(apply #'(lambda (x &optional (y (call-next-method)))
(body x y))
#:arguments)))))
∂12-Nov-87 1411 Common-Lisp-Object-System-mailer scope of call-next-method
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 12 Nov 87 14:11:43 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 278125; Thu 12-Nov-87 14:11:04 EST
Date: Thu, 12 Nov 87 14:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: scope of call-next-method
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871112105535.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871112191046.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 12 Nov 87 10:55 PST
From: Gregor.pa@Xerox.COM
I would still rather have call-next-method only be valid in the body of
the method and let users who want to do defaulting using it do the
defaulting by hand in the obvious way. I believe that the model that
defmethod wrap an flet around their body is a great deal simpler than
the model required to explain the behavior you propose.
I believe precisely the opposite, particularly since the way this is
explained to users surely does not involve writing out lambda
expressions and flets. That's only a way to explain it to implementors.
I think you're concentrating too much on the implementation and not
enough on the semantics. I propose that we leave call-next-method the
way it is and not change it.
I believe it's simpler to say that call-next-method works anywhere in a
method than to say it only works some places in a method, thus having to
say that if you use it in argument defaulting, you have to do the
argument defaulting a different way than you would ordinarily do it.
By the way, I tried the scoping you propose in Flavors, for the same
reason I think: I was concentrating too much on the implementation and
not enough on the semantics. My users forced me to change it to the
scoping I propose. These were outside users, not Symbolics people.
∂12-Nov-87 1821 Common-Lisp-Object-System-mailer Re: optimization in the spec
Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Nov 87 18:20:43 PST
Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Thu 12 Nov 87 17:36:47-PST
Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Thu, 12 Nov 87 14:38:47 PST
Received: from hplabsz.hpl.hp.com by hplms2.HP.COM; Thu, 12 Nov 87 14:38:25 pst
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 12 Nov 87 15:38:00 pst
To: Gregor.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: optimization in the spec
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 11 Nov 87 15:02:00 -0800.
<871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Thu, 12 Nov 87 15:37:57 MST
Message-Id: <27762.563755077@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM
> 1- Have an general, well worked out statement about what kinds of
> optimization are legal in CLOS implementations. This statement
> would be 'the optimization law'.
I think the general statement should be that no implementation should
perform an optimization which could cause a change in CLOS semantics.
This statement might, in fact, be TOO general, since it might rule
out things like in-lining slot access, which would cause the class
changing protocol to break. But in-lining slot access is a natural
optimization to want to do after code has been developed and the
class definition stabilizes, when the class changing protocol doesn't
matter any more. . So maybe the statement needs to be tied to the safety level.
> 2- Have an appendix or implementation notes in the document reflecting
> places in the design where the intent was to allow optimizations
> that are in accordance with the 'the optimization law'.
This is a good idea. The hints on optimization scattered about the
document should probably be gathered into an implementation notes
appendix, or (less preferable) set off from the text as in CLtL.
∂13-Nov-87 0833 Common-Lisp-Object-System-mailer Scope of Call-next-method
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Nov 87 08:33:36 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa07028; 13 Nov 87 11:18 EST
Received: from csl.ti.com by RELAY.CS.NET id aa12107; 13 Nov 87 11:18 EST
Received: from Jenner by tilde id AA24782; Fri, 13 Nov 87 09:01:33 CST
Message-Id: <2772802735-10721025@Jenner>
Date: Fri, 13 Nov 87 08:58:55 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Scope of Call-next-method
In-Reply-To: Msg of Thu, 12 Nov 87 14:10 EST from "David A. Moon" <Moon@scrc-stony-brook.arpa>
I believe it's simpler to say that call-next-method works anywhere in a
method than to say it only works some places in a method, thus having to
say that if you use it in argument defaulting, you have to do the
argument defaulting a different way than you would ordinarily do it.
Of course it is simpler to say that call-next-method works anywhere in a
method. An example will be make clear the fact that CALL-NEXT-METHOD
without arguments uses the method arguments, not its parameters.
Patrick.
∂13-Nov-87 1119 Common-Lisp-Object-System-mailer optimization in the spec
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 Nov 87 11:19:11 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 279096; Fri 13-Nov-87 14:19:05 EST
Date: Fri, 13 Nov 87 14:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: optimization in the spec
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111150223.5.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871113191855.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 11 Nov 87 15:02 PST
From: Gregor.pa@Xerox.COM
In the latest draft of the spec, there are several places which
explicitly address legal optimizations an implementation might perform.
I find these somewhat confusing, and I think that instead we might want
to do the following:
1- Have an general, well worked out statement about what kinds of
optimization are legal in CLOS implementations. This statement
would be 'the optimization law'.
2- Have an appendix or implementation notes in the document reflecting
places in the design where the intent was to allow optimizations
that are in accordance with the 'the optimization law'.
I think organizing it this way would be a good idea, although it could
involve a lot of work for a relatively small benefit. Also, in some cases,
such as object creation, it needs to be noted directly in the document that
the semantics have been relaxed to allow for increased optimization. This
was a very deliberate decision by the group, as I recall.
I don't have a good feel for whether it's better to describe these things
in terms of "optimization", as we do now, or simply to say that it is
implementation-dependent. The former way has the advantage of motivating
the reason for not requiring a particular behavior, while the latter is
more like CLtL.
As a start on this, here is a first crack on the law.
In order to insure program portability, there are strict rules which
must be followed when doing optimization of CLOS implementations. The
rules governing when error checking and signalling can be optimized away
have already been covered. Except where it is explicitly stated that
under certain compilation conditions it is permissible not to signal an
error, the rule governing optimizations is that no optimization can
change the behavior of a program. All optimizations must preserve the
semantics of the CLOS.
This is just a motherhood statement and begs the question "what, precisely,
are the semantics of CLOS."
We need
to make it clear that no user program will be able to detect
optimization (except for the stuff about an error should be signalled).
Of course user programs will be able to detect optimization, because we are
giving access to implementation-dependent details, for instance through the
meta-object protocol. Your statement is almost as strong as "it is impossible
to write a Common Lisp program that is not portable." I think what you really
mean is that CLOS defines a certain semantics that portable programs can
depend on, and optimizations, like everything else, must conform to that
semantics. That portable semantics does not fully specify every detail of
CLOS execution.
∂14-Nov-87 1453 Common-Lisp-mailer questions about CLOS [original subject: equality of structures]
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Nov 87 14:52:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 279905; Sat 14-Nov-87 17:52:14 EST
Date: Sat, 14 Nov 87 17:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: questions about CLOS [original subject: equality of structures]
To: goldman@vaxa.isi.edu
cc: COMMON-LISP@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <8711092000.AA14975@vaxa.isi.edu>
Message-ID: <19871114225202.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 09 Nov 87 12:00:35 PST
From: goldman@vaxa.isi.edu
Re: the suggestion that CLOS should subsume (by convention or otherwise)
uses of un:TYPEed defstruct types?
I presume that this takes care of the issue of EQUAL, because the CLOS
specifies the semantics of EQUAL for its class instances? (What is the
specification, by the way?)
CLOS does not currently say anything about how the functions EQUAL, EQUALP,
and EQL behave on instances of standard classes (you can read the last four
words as equivalent to "user-defined objects"). It also doesn't say
anything about the type-specific equality functions CHAR-EQUAL,
CHAR-NOT-EQUAL, TREE-EQUAL, STRING-EQUAL, and STRING-NOT-EQUAL, nor
the 6 type-specific = and /= functions.
It would fit the structure of CLOS to say that EQUAL and EQUALP will be
expanded to generic functions whose behavior can be extended by defining
methods. I don't think we would want to allow extending EQL or the
type-specific functions, since CLOS does not claim to be so powerful as
to allow you to create new types of numbers, characters, or strings.
Extending EQ would not make any sense, of course.
I suspect the reason CLOS currently shys away from EQUAL and EQUALP is
that the equality predicates in Common Lisp are clearly not very well
chosen and beg for a lot of cleaning up based on a better theory of what
we want. To give just one example, it's peculiar that comparing arrays
element-by-element has been bundled together with ignoring alphabetic case.
It's probably better to wait for Common Lisp to get its act together
before extending CLOS into this area; clearly, equality methods can be
added later to the standard or to an individual implementation without
any incompatibilities, so there's no rush.
A possible additional reason is that CLOS does not deal terribly well
with symmetric two-argument functions such as EQUAL. It's possible to
specialize them, but you usually have to define a lot of seemingly
extraneous methods, since the generic function dispatch mechanism has
no concept of commutativity nor of type translation.
But I would be loathe to replace my un:TYPEed
defstructs with DEFCLASSes if I gave up substantial efficiency when I only
wanted the limited power provided by the "record structure" semantics.
Are there enough declarations available in CLOS so that I could get
my compiled accesses to slots of such instances down to the equivalent
of an array element reference?
As an implementation-independent language specification, CLOS does not
and cannot directly address this issue. However, it's clear what would
generally need to be declared to allow implementations to do something
like that, although you would have to look at each individual implementation
to see whether it was faster or slower than arrays with declarations;
you might even find an implementation where slot access was faster than
array access even without declarations. Basically what you need to declare
is that the class cannot be redefined or subclassed. Some members of the
CLOS subcommittee volunteered to propose declaration names and syntaxes
to allow for this type of optimization, but they haven't finished yet.
However, it is intended that most CLOS implementations either be very
efficient or have a way to make them very efficient through declarations.
∂19-Nov-87 1714 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Nov 87 17:13:56 PST
Received: from Semillon.ms by ArpaGateway.ms ; 19 NOV 87 17:13:45 PST
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
Subject: symbol-macrolet
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
In the text in my draft, this would correspond to including something
like the following in remarks.
Within the body of symbol-macrolet the macroexpansion environment is
augmented to include a symbol-macro definition for the symbol. When
given the symbol and the environment as arguments, macroexpand-1 will
return the expansion. This means that a macro which appears in the
scope of symbol-macrolet can use macroexpand-1 to determine whether or
not a symbol names a symbol macro; this is particularly useful for
macros which want to determine whether or not their argument is a
symbol.
Examples:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form) environment))
`(* ,form ,form)
`(expt ,form 2)))
This is a pretty lame example. Hopefully we can come up with something
else that is as simple but more compelling.
Also, we may want to mention explicitly the zetalisp macro once-only.
-------
∂20-Nov-87 0343 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from [128.89.1.216] by SAIL.STANFORD.EDU with TCP; 20 Nov 87 03:43:30 PST
To: Gregor.pa@XEROX.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-macrolet
In-reply-to: Your message of Thu, 19 Nov 87 17:13:00 -0800.
<871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>
Date: Fri, 20 Nov 87 06:37:20 -0500
From: kanderso@WILMA.BBN.COM
I think there was an obvious bug in your example. How about:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form) ; <-
`(* ,form ,form)
`(expt ,form 2)))
I tried to come up with another example. This is more generic
(dispatching on whether the form is a symbol or not) but it seems
more lame.
(defun dispatch (form &optional environment)
(if (symbolp form)
(setq form (macroexpand-1 form environment)))
(if (and (symbolp form)
(special-symbol form))
(dispatch-special-symbol form environment)
(dispatch-form form envrionment)))
k
∂20-Nov-87 0944 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Nov 87 09:44:27 PST
Received: from Semillon.ms by ArpaGateway.ms ; 20 NOV 87 09:44:09 PST
Date: Fri, 20 Nov 87 09:43 PST
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-macrolet
To: kanderso@WILMA.BBN.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 20 Nov 87 03:37 PST from
kanderso@WILMA.BBN.COM
Message-ID: <871120094332.9.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Fri, 20 Nov 87 06:37:20 -0500
From: kanderso@WILMA.BBN.COM
I think there was an obvious bug in your example. How about:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form) ; <-
`(* ,form ,form)
`(expt ,form 2)))
Oops, you're right. I forgot NOT. Instead it should be:
(defmacro ↑2 (form &optional environment)
(if (and (symbolp form)
(not (eq (macroexpand-1 form environment) form)))
`(* ,form ,form)
`(expt ,form 2)))
-------
∂20-Nov-87 1455 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Nov 87 14:55:13 PST
Received: from Semillon.ms by ArpaGateway.ms ; 20 NOV 87 14:54:54 PST
Date: Fri, 20 Nov 87 14:54 PST
From: Gregor.pa@Xerox.COM
Subject: Re: symbol-macrolet
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: kanderso@WILMA.BBN.COM
In-Reply-To: <871120094332.9.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <871120145418.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
OK, lets try this again. Maybe I will get it right this time:
I am not supposed to have the NOT, and environment is an &environment
argument not an &optional argument. Also today is Friday, its daylight,
and my name is Gregor. I think I have it now.
(defmacro ↑2 (form &environment environment)
(if (and (symbolp form)
(eq (macroexpand-1 form environment) form))
`(* ,form ,form)
`(expt ,form 2)))
-------
∂23-Nov-87 1041 Common-Lisp-Object-System-mailer Re: symbol-macrolet
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 23 Nov 87 10:41:08 PST
Received: from relay2.cs.net by RELAY.CS.NET id ae10335; 23 Nov 87 13:31 EST
Received: from csl.ti.com by RELAY.CS.NET id au19978; 23 Nov 87 13:24 EST
Received: from Jenner by tilde id AA17820; Mon, 23 Nov 87 11:21:58 CST
Message-Id: <2773675077-8251807@Jenner>
Date: Mon, 23 Nov 87 11:17:57 CST
From: Patrick H Dussud <DUSSUD%jenner.csc.ti.com@RELAY.CS.NET>
To: Gregor.pa@XEROX.COM
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: symbol-macrolet
In-Reply-To: Msg of Fri, 20 Nov 87 14:54 PST from Gregor.pa@xerox.com
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
In the text in my draft, this would correspond to including something
like the following in remarks.
Within the body of symbol-macrolet the macroexpansion environment is
augmented to include a symbol-macro definition for the symbol. When
given the symbol and the environment as arguments, macroexpand-1 will
return the expansion. This means that a macro which appears in the
scope of symbol-macrolet can use macroexpand-1 to determine whether or
not a symbol names a symbol macro; this is particularly useful for
macros which want to determine whether or not their argument is a
symbol.
It sounds good.
Patrick.
∂23-Nov-87 1220 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Nov 87 12:20:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 286861; Mon 23-Nov-87 15:19:41 EST
Date: Mon, 23 Nov 87 15:19 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: symbol-macrolet
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871119171306.3.GREGOR@SPIFF.isl.parc.xerox.com>,
The message of 20 Nov 87 06:37 EST from kanderso@WILMA.BBN.COM,
<871120094332.9.GREGOR@SPIFF.parc.xerox.com>,
<871120145418.2.GREGOR@SPIFF.parc.xerox.com>,
<2773675077-8251807@Jenner>
Message-ID: <19871123201936.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
I thought we were going to allow SYMBOL-MACROLET to be implemented in a
portable way, as something that fully macroexpands the form given and
then makes substitutions for symbols in it. During macroexpansion the
symbol-macrolet'ed symbols would be just like other symbols, which seems
okay since they are (I think) supposed to be used in ways that are
semantically like variables; certainly that's true in the case of
WITH-SLOTS.
You seem to be suggesting that instead we will require every
implementation to change its macro mechanism to support symbol macros
directly. Does this also require that every implementation must change
its interpreter and compiler to macroexpand symbols as well as lists
before attempting to evaluate them? Whether the answer to that is yes or
no, it seems likely that every implementation would have to change its
internal representation of lexical environments, to allow for symbols to
be "bound" to macros as well as to values. We might get a great deal of
resistance to that from some implementations.
Unless we can come up with some more compelling examples than so far, I
don't think CLOS should require SYMBOL-MACROLET to do anything to the
macroexpansion environment. I think we should stick with the very
simple and easy to understand definition of SYMBOL-MACROLET that we have
now: "Each reference to -symbol- as a variable within the lexical scope
of symbol-macrolet is replaced by -expansion-." Both examples so far
appear to be predicated on the assumption that a call to SLOT-VALUE is
much less efficient than accessing a variable, and therefore we want to
allow for common subexpression optimization to be done by hand for these
in a funny way. I for one see no reason to stipulate that inefficiency,
nor to assume that CSE optimizations must be done by hand.
∂23-Nov-87 1306 Common-Lisp-Object-System-mailer symbol-macrolet
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Nov 87 13:06:30 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 NOV 87 13:05:11 PST
Date: Mon, 23 Nov 87 13:04 PST
From: Gregor.pa@Xerox.COM
Subject: symbol-macrolet
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <19871123201936.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <871123130424.8.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Date: Mon, 23 Nov 87 15:19 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Thu, 19 Nov 87 17:13 PST
From: Gregor.pa@Xerox.COM
I suppose we should say explicitly that the symbol macros are recorded
in the macroexpansion environment so that macroexpand-1 of a symbol
which is a symbol-macro will expand it.
I thought we were going to allow SYMBOL-MACROLET to be implemented in a
portable way, as something that fully macroexpands the form given and
then makes substitutions for symbols in it. During macroexpansion the
symbol-macrolet'ed symbols would be just like other symbols, which seems
okay since they are (I think) supposed to be used in ways that are
semantically like variables; certainly that's true in the case of
WITH-SLOTS.
You seem to be suggesting that instead we will require every
implementation to change its macro mechanism to support symbol macros
directly. Does this also require that every implementation must change
its interpreter and compiler to macroexpand symbols as well as lists
before attempting to evaluate them? Whether the answer to that is yes or
no, it seems likely that every implementation would have to change its
internal representation of lexical environments, to allow for symbols to
be "bound" to macros as well as to values. We might get a great deal of
resistance to that from some implementations.
Unless we can come up with some more compelling examples than so far, I
don't think CLOS should require SYMBOL-MACROLET to do anything to the
macroexpansion environment. I think we should stick with the very
simple and easy to understand definition of SYMBOL-MACROLET that we have
now: "Each reference to -symbol- as a variable within the lexical scope
of symbol-macrolet is replaced by -expansion-." Both examples so far
appear to be predicated on the assumption that a call to SLOT-VALUE is
much less efficient than accessing a variable, and therefore we want to
allow for common subexpression optimization to be done by hand for these
in a funny way. I for one see no reason to stipulate that inefficiency,
nor to assume that CSE optimizations must be done by hand.
Well, my concern was that there were macros which use once-only for
semanic reasons rather than purely optimization reasons. These macros
assume that if a variable is lexical, they can know whether that
variable is being modified in their scope, they can perform some
optimizations. Granted, this is bad macro writing style, but I claim
that it is common. Its also true that the cases where these macros will
break is rare, but they do exist, and it makes me uncomfortable to think
there will be no way of fixing them.
On the other hand, I agree that it makes me unhappy to have to modify
the behavior of macroexpand-1 this way, and to modify the behavior of
the interpreter this way. I had not realized that this was such a
radical change.
I guess now I am not sure. Maybe the best thing to do is leave
symbol-macrolet the way you suggested and just document the exact form
of lossage I am describing.
Let me take this space to present one view of how macroexpansion
environments could be made more useful. If they were themselves a
function, which could be given an operation and arguments, and if the
default function accepted operations to macroexpand-1, fboundp, etc.
then I could just extend these things by wrapping my own function around
them which carried additional information. That would make it possible
to write a portable code walker in Common Lisp. But it would not solve
this problem.
-------
∂23-Nov-87 1758 Common-Lisp-Object-System-mailer making gf lambda lists
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Nov 87 17:57:54 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 287364; Mon 23-Nov-87 20:57:15 EST
Date: Mon, 23 Nov 87 20:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: making gf lambda lists
To: Gregor.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <871111144109.3.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <19871124015712.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No
Date: Wed, 11 Nov 87 14:41 PST
From: Gregor.pa@Xerox.COM
I believe that we are going to want to introduce a support function
called something like:
make-generic-function-lambda-list-from-specialized-method-lambda-list
This function will make it easier for programmers who are constructing
their own methods and generic functions to get themselves a congruent
generic function lambda list. This functions will strip out
specializers and optional defaults and remove uses of &key and &aux (and
anything else I might have forgotten).
Can anyone think of a better name for this function?
No name.
I have too much mail backlog to find it now, but I think I suggested
that the making of a generic function should accept any form of lambda
list and should strip it itself. Maybe I only suggested that for
methods, but I think it should apply to both methods and generic
functions that you can hand in anything that can be coerced into the
right thing. "Hand in" means as a :lambda-list argument to
ensure-generic-function or to make-instance of the appropriate class.
It's always a metter of philosophy whether to bring functions like
this that we know are in there someplace out into the open and give
them documented names. I like the SETF approach, which says to
document only the ones that the user really has to know about.
∂24-Nov-87 1144 Common-Lisp-Object-System-mailer Re: making gf lambda lists
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Nov 87 11:44:03 PST
Received: from Semillon.ms by ArpaGateway.ms ; 24 NOV 87 11:39:14 PST
Date: Tue, 24 Nov 87 11:36:03 PST
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: making gf lambda lists
In-Reply-To: <19871124015712.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: Gregor.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <871124-113914-4047@Xerox>
> It's always a metter of philosophy whether to bring functions like
this
> that we know are in there someplace out into the open and give them
documented
> names. I like the SETF approach, which says to document only the
ones
> that the user really has to know about.
I agree with the philosophy but find it curious that the proposal to
have SETF named functions is to remedy the fact that the SETF macro
approach hides things which people discovered they sometimes need.
References
Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Mon, 23 Nov 87
20:57:00 EST -- making gf lambda lists